# Kintsugi API Docs > Developer documentation for the Kintsugi sales tax API. Calculate tax, sync transactions and customers, manage registrations and nexus, and work with filings. This file indexes the guides, the v1 API reference, and the Tenanted API reference. This file carries the full text of every public page. For the linked index, see https://docs.trykintsugi.com/llms.txt. --- # Getting Started with Kintsugi Connect your sales data, configure your business, and get Kintsugi calculating, registering, and filing sales tax on your behalf Source: https://docs.trykintsugi.com/docs/getting-started Kintsugi automates sales tax end to end. It watches where your sales create an obligation, prices the right rate at checkout, registers you in the jurisdictions that require it, and files and remits on schedule. Setup is five steps, and this page covers all of them. What to expect: the first three steps are yours to complete and take an afternoon at most. Registrations move at the speed of each state's tax authority, so plan for those to land over days rather than minutes. Quick Setup The five steps, in order, from connecting data to approving your first filing. Plan an Integration Choose between transaction sync (L1) and the tax engine (L2) before you write code. API Keys and Authentication Create a key, then make your first authenticated request. API Reference Every endpoint, with real request and response shapes from the live spec. ## Quick Setup Five steps, in order. Each one unlocks the next: Kintsugi cannot price a product it has not classified, and cannot file a return in a jurisdiction where you are not registered. Connect Your Data Kintsugi works from your sales history. Nexus, rates, and returns are all derived from the transactions you send, so connecting a data source comes first. Open Data Sources in the app and click Connect, then choose the route that matches your stack. Direct Integration Dozens of prebuilt connectors cover shopping carts, billing systems, ERPs, and accounting platforms. Pick your platform, authorize it once, and Kintsugi keeps transactions in sync from then on. Custom Integration Build against the REST API or an official SDK. Start with Planning an Integration to choose your integration level, then Syncing Transaction Records for the payload shape. SDKs are available for Python, TypeScript, Java, PHP, and Ruby, and the API Lab lets you run each workflow before you build it. CSV Upload Download Kintsugi's template, fill it in, and upload it. File Upload documents every column the importer reads, and uploaded transactions behave exactly like ones created through the API. Import Historical Data Send transactions covering the previous full calendar year through today. Kintsugi determines nexus by looking back across that window, so without it we cannot tell you when you crossed a threshold or when your filing obligation began. CSV is usually the fastest way to backfill: see File Upload for the template and column reference. Coming from another provider? Migrating from Avalara or TaxJar covers exporting your history and cutting over without breaking a filing period. ## Quick Setup Skipping history does not stop Kintsugi from tracking new sales, but it does mean nexus start dates and past exposure have to be set from your own records. Import the history if you have it. Configure Your Business Kintsugi needs three things about your company: where you have people and property, who you are on a tax return, and how you pay. Physical Presence Economic nexus comes out of your transaction data automatically. Physical nexus does not, because no transaction records it. Tell Kintsugi where you have: Offices, stores, or warehouses Employees or contractors, including remote staff working from home Inventory held for sale, including stock in a third-party fulfillment center you have never visited Traveling sales representatives If you are unsure, enter what you know and Kintsugi flags the jurisdictions worth a second look. US Sales Tax for Developers explains how each activity creates an obligation, and physical nexus can also be managed programmatically through Create physical nexus. Physical nexus carries no grace threshold. Unlike economic nexus, it applies from your first taxable sale into that state, so record presence as soon as it exists. Organization Details These details appear verbatim on your registrations and returns, so match them to your incorporation documents rather than your brand name: Legal business name and address Tax ID numbers Entity type and industry Contact for jurisdiction correspondence Banking Information Kintsugi debits the tax it remits on your behalf, so bank details are required before your first filing rather than before setup: Bank account for tax payments ACH authorization Payment preferences Banking details are encrypted at rest and used only to remit tax on your behalf. ## Quick Setup Classify Products and Validate Addresses Two inputs decide every rate Kintsugi calculates: what you sold, and where it went. Product Classification Taxability is decided per product, not per order. A t-shirt, a downloadable report, and a SaaS subscription are treated differently in the same state, so each product needs a category before Kintsugi can price it. Approving a product means confirming the category assigned to it. Kintsugi Intelligence Let Kintsugi Intelligence classify the catalog, then spot-check the results. The best starting point for a large catalog. Bulk Approval Use bulk approve to accept the assigned categories across the catalog in one action. Fastest when your products are uniform. Manual Review Set the category product by product. Worth the time for bundles, digital goods, and anything with unusual treatment. Product Categories explains how categories and subcategories map to taxability, and Get product categories returns the full catalog of values. Creating products through the API instead? See Create a product. Address Validation A rate is a function of an address, not a state. A postal code resolves to a county, city, and any special districts on top; a state on its own does not, and the gap between the two is often several percent. Open Tasks to see the transactions Kintsugi could not resolve Use Kintsugi Intelligence to fill in missing components Review anything still flagged, since these are the rows most likely to be wrong on a return Validate addresses in your own checkout before you calculate tax, and you avoid the correction later. See Address validation for the endpoint. Review Nexus and Exemptions With data and configuration in place, Kintsugi can tell you where you owe and who is exempt. Nexus Review ## Quick Setup Open Nexus to see where you have crossed a threshold, where you are approaching one, and where you have no obligation yet. The exposure map on your dashboard is the same picture, by geography. Kintsugi monitors nexus continuously and alerts you when a new obligation appears, so this is a review rather than something to recheck by hand. Reading it programmatically: Get nexus for org. Exemption Management If you sell to resellers, nonprofits, or government buyers, record the exemption before you collect tax you will have to refund: Configure customer exemptions in the Exemptions section Set product-level exemptions where a category is treated differently Upload and manage exemption certificates so they are on file for an audit Through the API: Create an exemption and Upload an exemption certificate. Register, File, and Remit Nexus tells you where you owe. A registration is what makes filing possible, so this is the step that turns monitoring into compliance. Register in New Jurisdictions Click Register on the Nexus page for each jurisdiction where you have nexus. Kintsugi handles the application; processing time is set by the state, not by us. Import Existing Registrations Already registered somewhere? Import the registration with its effective date and filing frequency so Kintsugi picks up returns from the right period rather than the day you signed up. See Create a registration. File and Remit Review your returns on the Filings page and click Approve to file and remit in each jurisdiction. Get filings exposes the same records to your own systems. Once a jurisdiction is registered and its first filing is approved, Kintsugi files and remits there on schedule without further action from you. ## Next Steps Setup is done. Where you go next depends on whether you are operating Kintsugi or building on it. Create an API Key Generate a key and store it safely. Make Your First Request Authenticate with your key and organization ID. Plan an Integration Pick L1 or L2, then sequence the build. API Lab Run each workflow interactively before you code it. US Sales Tax for Developers Nexus, taxability, exemptions, and sourcing explained. Kintsugi MCP Point your AI coding assistant at the live API and docs. Day to day, the records you will read most are customers, transactions, and registrations. ## Need Help? Common Questions Setup Issues Integration will not connect? Recheck the credentials and permissions on the connection in Data Sources, then see Error Handling for what the response is telling you. Data not syncing? Confirm your API key is active and that every request carries both x-api-key and x-organization-id. See Making an Authenticated Request. Tax calculations look wrong? Check the product's classification first and the destination address second. Those two inputs account for most surprises. See Product Categories. Nexus dates look wrong? Usually a gap in historical data. See Syncing Transaction Records. Account Management Change your business information: Settings > Organization. These values flow to registrations and returns, so update them before your next filing. Add team members: the Users section of your dashboard. Update billing: the Help Center covers subscriptions, invoices, and payment methods. Technical Support Endpoint details: the API Reference is generated from the live spec. Client libraries: SDKs for Python, TypeScript, Java, PHP, and Ruby. Error responses: Error Handling covers status codes, retries, and idempotency. Building with an AI assistant: Kintsugi MCP gives it the current spec instead of a stale copy. Get Support Email Support Reach our support team at success@trykintsugi.com. Phone Support Call +1 (415) 840-8847. Live Chat Chat with us in real time. Help Center Product, billing, and filing guides, outside the developer docs. FAQ Answers to the questions we hear most. Community Coming soon Connect with other Kintsugi users. --- # Creating and Managing API Keys Create an API key in the Kintsugi app, store it safely, and rotate or revoke it later Source: https://docs.trykintsugi.com/docs/getting-started/creating-and-managing-api-keys Every Kintsugi API request carries two headers: an API key and an organization ID. This page covers creating a key in the app, the one moment you can copy it, and how to manage keys after that. Create Your First Key Four clicks in the Configuration page. Store It Safely The key is shown once and never again. Make an Authenticated Request Send your key and organization ID, and confirm they work. API Reference Every endpoint your key can reach. ## Before You Start You need an account on the Kintsugi platform and access to an organization. Keys can only be created in a Test or Paid organization. In any other organization type the option is disabled, so check which one you are signed in to before you start. A key is scoped to one organization and grants the API access that organization has. You can hold several at once, which is what makes rotation possible without downtime. ## Create an API Key Open the API Keys Tab Sign in to the Kintsugi platform. If you do not have an account yet, sign up first. Select Configuration in the left sidebar, below Tools. Configuration sits at the bottom of the sidebar, above your name and the organization switcher. Configuration opens on a row of tabs. Select API Keys. Configuration tabs: API Keys sits between Users and Exemptions. The tab lists every key belonging to the organization you are signed in to, with a search box, a link back to this documentation, and a New button. A new organization has none yet. The API Keys tab before any key exists. Create a New API Key Click New. The New Organization API Key dialog opens, named for the scope the key will have. Choose when the key should expire: Never, One Month, Six Month, or One Year. Expiry is the only decision the dialog asks you to make. Pick the shortest window that covers the work. An expiring key limits how long a leaked one is useful, and the expiry date is the reminder to rotate. One Month suits local development and spikes, One Year suits a production integration you will rotate on schedule, and Never is worth choosing only when something other than the calendar will retire the key. Confirm to generate the key. Copy and Secure Your API Key This is the only time the key is visible. Copy it before you close the dialog. There is no way to reveal it again, so a key you did not copy has to be deleted and replaced. Click the copy icon, or Manually copy API key to select the full value yourself. Copy the key here, or lose it. Paste it straight into wherever your application reads secrets from, before you do anything else. Click Done. Three habits worth keeping from the start: ## Create an API Key Read the key from the environment, never from source. A key in a commit is a key in your history, and rewriting history is a worse afternoon than rotating a key. Use a separate key per application and environment. Keys are independent, so one can be revoked without taking the others down with it. Share through a password manager, not chat or email. Viewing and Managing Your API Keys The API Keys tab lists each key with its truncated value under KEY, plus its CREATED and EXPIRES dates. Only the truncated form is ever shown again. Use the search box to find a key, and the three-dot menu (⋮) at the end of its row to delete it. An existing key, and the delete action on its row menu. Deleting a key takes effect immediately and cannot be undone. Anything still using it starts getting 401 Unauthorized on the next call, so put the replacement in place first. See Error Handling for what an authentication failure looks like. ## Rotating a Key Because an organization can hold several keys at once, rotation needs no downtime and no maintenance window: Create the replacement Generate a new key alongside the one you are retiring. Deploy it Update the secret your application reads and roll it out. Confirm the new key is live Make a request and check it succeeds. Making an Authenticated Request is the quickest check. Delete the old key Only once nothing is using it. Deleting first is what turns a rotation into an outage. Set expiry when you create the key and rotation stops being something you have to remember. The EXPIRES column is your schedule. ## Next Steps Make an Authenticated Request Send x-api-key and x-organization-id, and find your organization ID. Plan an Integration Choose L1 or L2 before you write code. SDKs Python, TypeScript, Java, PHP, and Ruby clients that handle the headers. API Lab Run each workflow interactively before you build it. Error Handling Status codes, retries, and what a rejected key returns. Kintsugi MCP Give your AI coding assistant the live API and docs. ## Need Help? Common Issues Creating a Key No API Keys tab, or New is unavailable? Keys can only be created in a Test or Paid organization. Check the organization switcher in the lower left. Permission denied? Key management is an admin action. Ask an admin on your organization, in the Users tab. Key not generating? Reload the Configuration page and try again. If it persists, contact support. Using a Key 401 Unauthorized? The key is wrong, expired, or deleted. Check the EXPIRES column, and check the header name is x-api-key exactly. 403 Forbidden? The key is valid but the organization is wrong. x-organization-id has to match the organization the key was created in. Header names: lowercase with hyphens, both required. See Making an Authenticated Request. Reading the response: Error Handling covers each status code. Lost or Leaked Keys Lost the key? It cannot be recovered. Delete it and create another. Key leaked? Delete it immediately, then create and deploy a replacement. Deleting is instant. Committed a key to git? Delete the key first, then clean the history. Revoking is what actually stops it being used. Which key is which? Match the truncated value in the KEY column against the start of the key your application holds. Get Support Email Support Reach our support team at success@trykintsugi.com. Phone Support Call +1 (415) 840-8847. Live Chat Chat with us in real time. Help Center Product, billing, and filing guides, outside the developer docs. API Reference Every endpoint, generated from the live spec. Developer Community Coming soon Connect with other developers building on Kintsugi. --- # Authenticating Your Requests Send your API key and organization ID on every request, verify they work, and read what a rejected call is telling you Source: https://docs.trykintsugi.com/docs/getting-started/authentication Kintsugi authenticates every request with two headers: x-api-key identifies you, and x-organization-id says which organization you are acting for. There is no bearer token, no OAuth flow, and no session to keep alive. The Two Headers What each one is, and where to get it. Your First Request One call that verifies your credentials without changing anything. When a Request Is Rejected What 401, 403, and 405 are each telling you. API Reference Every endpoint, with a ready-made request for each. ## Before You Start You need two values: An API key. Create one in the app: Creating and Managing API Keys. Your organization ID. Sign in to the Kintsugi platform and look at the organization switcher in the lower left of the sidebar, below your name. ## The Two Headers Every request goes to https://api.trykintsugi.com and carries both: | Header | What it is | Example | | --- | --- | --- | | x-api-key | The key you created in the app. Identifies the caller. | 02f51ad8c56fde0f82702e08c8546257… | | x-organization-id | Which organization the request acts on. | org_12345 | A key is issued against one organization and only works with that organization's ID, so the two values travel together. Sending one without the other fails. HTTP header names are case-insensitive, so x-api-key and X-API-KEY are the same header. The API Reference shows the uppercase form and the examples here use lowercase; either is fine, and it is worth picking one and staying with it. These headers belong on your server, never in a browser or a mobile app. Anything shipped to a client is readable by whoever holds it, and a leaked key can act on your whole organization. Call Kintsugi from your backend and let your own frontend talk to that. ## Your First Request Start with a read. GET /v1/products/categories returns Kintsugi's product category catalog, takes no parameters, and works on an organization with no data in it yet, which makes it a clean way to prove your credentials without creating anything: curl https://api.trykintsugi.com/v1/products/categories \ -H "x-api-key: $KINTSUGI_API_KEY" \ -H "x-organization-id: $KINTSUGI_ORG_ID" A 200 with a JSON body means both headers are good and you are ready to build. Read the key from the environment, as above, rather than pasting it into the command. That keeps it out of your shell history as well as out of your source. See Get product categories for the response shape. Once that works, every other endpoint takes the same two headers. The API Reference carries a ready-made request for each one, and the API Lab runs whole workflows interactively so you can see the sequence before you write it. ## When a Request Is Rejected Authentication failures are specific, and which code comes back tells you where to look: | Code | What went wrong | Where to look | | --- | --- | --- | | 401 Unauthorized | The key was missing, misspelled, expired, or deleted. | Check the header name, then the EXPIRES column on the API Keys tab. | | 403 Forbidden | The key is valid but not for that organization. | x-organization-id has to be the organization the key was created in. | | 405 Method Not Allowed | Your credentials were fine; the verb was wrong. | Check the method in the reference. POST /v1/tax/estimate, for example, rejects a GET. | Error Handling covers the full set of status codes, the error response body, and retry behavior. ## Using an SDK Instead The official SDKs take the key and organization ID once when you construct the client and set both headers on every call, so there is nothing per-request to remember: SDK Quick Start Install a client and make your first authenticated call. All SDKs Python, TypeScript, Java, PHP, and Ruby. Kintsugi MCP Point your AI coding assistant at the live API and docs. ## Next Steps Plan an Integration Choose transaction sync (L1) or the tax engine (L2) before you write code. Calculate Tax The endpoint most integrations reach for first. Sync Transactions Record completed sales, which is what nexus is derived from. API Lab Run each workflow interactively before you build it. Error Handling Status codes, retries, and idempotency. Rotate Your Key Swap a key with no downtime. --- # US Sales Tax for Developers The concepts behind every tax calculation: nexus, product taxability, exemptions, sourcing, and marketplace facilitator rules Source: https://docs.trykintsugi.com/docs/guides/sales-tax-for-developers Building e-commerce platforms, SaaS applications, and marketplaces means working inside one of the most fragmented regulatory systems in software: US sales tax. There is no federal sales tax and no single rulebook. Instead there are 45 states and the District of Columbia that impose one, local jurisdictions in Alaska that impose their own, and more than 11,000 taxing jurisdictions in total, each with its own rates, thresholds, and definitions of what counts as taxable. This guide covers the concepts that decide the number on the invoice. Get these right and the API calls are straightforward. For implementation details, see the Tax Estimate guide and the API Reference. ## The Four-Factor Taxability Framework Sales tax is not a yes or no decision. Every transaction runs the same four checks, in this order, and the first "no" ends it and returns zero tax. 1 Nexus Do you owe anything in this state at all? Physical presence or crossed economic thresholds in the destination state. See nexus types below. NO → No tax. Kintsugi keeps counting the sale toward the state's threshold anyway, so your exposure stays accurate. The response says which side of the line you landed on: nexus_met for the obligation, has_active_registration for the permit that lets you collect against it. 2 Product taxability Is this thing taxable here? Driven by the item's product category. Groceries, apparel and SaaS all swing state by state. NO → Exempt product. Nothing to collect on that line, and exempt_reason names the rule that zeroed it. 3 Customer exemption Is this buyer exempt? Resellers, nonprofits and government buyers, backed by a certificate on file. YES → No tax, and the certificate is what defends the exemption in an audit. Kintsugi applies a customer's exemptions when the transaction's external_id matches a customer on file. For a one-off that belongs to no customer record, set exempt: true on the line instead. 4 Sourcing Whose rate applies? Destination states use the ship-to address; a handful of origin states use where the sale shipped from. This picks which jurisdictions stack up, never whether tax is due. All four pass, so tax is due The rate is the sum of every jurisdiction that applies at that address: state, county, city, and any special district. At checkout Collect the tax Charged to the buyer, held by you. On the filing date Remit and file Kintsugi files the return in each jurisdiction. ## The Four-Factor Taxability Framework Order matters, and check 2 needs data from you. An item Kintsugi cannot classify is rejected rather than taxed at zero, so send a known external_product_id, or a category and subcategory pair, on every line. 1. Nexus - The Business Connection Does your business have a connection to this state? Without nexus you have no obligation to collect in that jurisdiction. Nexus comes in two forms: Physical nexus: offices, warehouses, employees, inventory Economic nexus: sales volume or transaction count thresholds Remote employees create physical nexus in the state where they work, even from a home office. So does inventory sitting in a third-party fulfillment center you have never visited. 2. Product Taxability - What's Actually Taxable Is this product or service taxable in this state? Taxability is set by the item's product category, and it varies sharply by state: Physical Goods Almost always taxable: electronics, furniture, general merchandise Often exempt: groceries, prescription drugs, medical devices State-specific: clothing, which is exempt in Pennsylvania, taxable in California, and exempt below a price cap in New York and Massachusetts Digital Products Taxable: Colorado, Connecticut, Hawaii, Texas, Washington Generally exempt: California, Florida, Nevada Digital goods and software are separate questions in many states, so treat them separately SaaS Taxable: New York, Texas, Pennsylvania, Washington, Massachusetts, Ohio Generally exempt: California, Florida, Virginia Some states tax business use and exempt personal use, or the reverse Services Generally exempt: most states, historically Broadly taxable: Hawaii, New Mexico, South Dakota, West Virginia Selective: repair, installation, and some professional services, state by state ## The Four-Factor Taxability Framework Taxability rules change every legislative session, and digital products and services are where they change fastest. Kintsugi maintains the current rules, so classify the product correctly and let the platform resolve the rate. 3. Customer Exemptions - Who Gets Special Treatment Does this buyer qualify for an exemption? Commonly exempt buyers: Businesses purchasing for resale Government agencies Nonprofit organizations Educational institutions Exemptions apply in two ways. When the transaction's external_id matches a customer on file, Kintsugi applies that customer's exemptions automatically. For a one-off that belongs to no customer record, set exempt: true on the line item. An exemption is only as good as its certificate. Selling tax-free without valid documentation on file leaves you liable for the tax an auditor says you should have collected, plus penalties and interest. 4. Sourcing - Where to Apply the Rate Which address determines the rate? Destination-based: the buyer's delivery address, which covers nearly every state and every remote sale Origin-based: the seller's location, which a handful of states use for sales inside their own borders Sourcing decides which rate applies. It never decides whether tax is due. See Sourcing Rules below. ## Nexus Types: Physical vs Economic Before 2018, a state could only tax sellers with a physical presence inside it. South Dakota v. Wayfair removed that limit, and every state with a sales tax now also asserts economic nexus. The two are independent, and one is enough. Type A Physical nexus Something of yours is in the state. Any one of these triggers it Offices, stores and warehouses Employees and contractors, including remote staff Inventory storage, including 3PL Trade shows and events Obligation starts Immediately Register before the first taxable sale. There is no grace threshold. Type B Economic nexus You sold enough into the state. Usually either one triggers it Sales volume Commonly $100,000, measured over a rolling year or a calendar year. Transaction count Often 200 sales, though many states have dropped it. Obligation starts On the effective date The state sets it once you cross. Register, then collect from that date. Thresholds, measurement windows and combination rules all vary. New York needs both $500,000 and more than 100 sales; California and Texas look at $500,000 in sales alone. Kintsugi tracks the live values per state, so treat these numbers as shape, not law. Nexus and registration are different things. Nexus is the obligation; a registration is the permit that lets you collect against it. Kintsugi calculates tax where you hold an active registration, and the estimate response reports both nexus_met and has_active_registration so you can tell a zero-tax sale from an unregistered one. Monitor Sales by State Track revenue and transaction counts per state against that state's own threshold, window, and combination rule. Set Up Threshold Alerts Watch for states you are approaching, not just states you have crossed. Registration takes time. Register Before Collecting ## Nexus Types: Physical vs Economic Collecting sales tax without a permit is unlawful in every state that levies it. The money is not yours to hold. Collect From the Effective Date Start collecting on the date the permit takes effect, which is not always the date you applied or the date it arrived. ## Sourcing Rules: Origin vs Destination You have nexus and a taxable product. One question remains: whose rate applies? Remote sales are always destination-sourced. Origin sourcing is a rule for intrastate sales, where the seller has a location in the same state as the buyer. If you are a remote seller with economic nexus and no presence in the state, use the ship-to address regardless of that state's intrastate rule. Destination-Based Sourcing The rate follows the buyer's delivery address How it works: A Los Angeles merchant charges the San Diego rate on a San Diego delivery Every delivery address is potentially a different rate With more than 11,000 jurisdictions in play, the rate is an address lookup, not a state lookup Kintsugi resolves the rate from the SHIP_TO address on the transaction, falling back to BILL_TO when no SHIP_TO is present. Sending a complete, validated ship-to address is the highest-leverage thing you can do for rate accuracy. Origin-Based Sourcing The rate follows the seller's location, for intrastate sales only States: Arizona, Illinois, Mississippi, Missouri, Ohio, Pennsylvania, Tennessee, Texas, Utah, Virginia. California is a hybrid, below. How it works: An Austin merchant with a Texas location charges the Austin rate to Texas customers Same rate whether the order ships to Dallas, Houston, or rural West Texas Cheaper to compute, and it concentrates local revenue where businesses sit California's Hybrid Sourcing Two sourcing rules on one order State, county, and city taxes: origin-based District taxes: destination-based A single California order can therefore draw on both the seller's and the buyer's address, which is why California is the state most worth testing against real addresses rather than assumptions. ## Marketplace Facilitators Every state with a sales tax now has marketplace facilitator legislation, which moves the duty to collect from the seller to the platform. Whether it applies to you comes down to one question: does the platform take the buyer's money? Platform processes payment Facilitator Amazon, eBay, Etsy, Walmart, TikTok Shop Calculates tax Platform Remits and files Platform Counts toward your nexus By state You do not register for these sales Import them anyway so your exposure picture is complete. You process payment Storefront Shopify, WooCommerce, your own checkout Calculates tax You Remits and files You Counts toward your nexus Always Compliance is yours end to end This is the path the four checks describe. Most sellers run both at once, and nexus is measured on you as a business, so the two channels have to be read together. Whether facilitated sales count toward your own thresholds is a per-state rule, which Kintsugi carries on the nexus record as marketplace_included. Selling on both is the normal case. Marketplace sales being handled by the platform does not exempt you from registering for your direct sales, and it does not undo physical nexus you already have in that state. Segregating facilitated from direct sales in your own reporting is what keeps the two straight at filing time. ## Collection Timeline Sales tax obligations follow a sequence, and every step in it is a date your system should know. Home State Registration Register before your first sale. Most states require a permit regardless of volume once you are operating there. Physical Nexus Registration Register before your first taxable sale into a state where you have presence. Physical nexus carries no grace threshold. Economic Nexus Monitoring Track sales by state and register once you cross. The deadline runs from the crossing date and varies by state, so record the date you crossed, not just the fact that you did. Begin Collection Collect from the effective date of your permit, and apply the rate for the buyer's address on every order from that point. File Returns File and remit on the frequency the state assigns, whether monthly, quarterly, or annually. File even for periods with no sales: most states require a zero return, and missing one draws a penalty on nothing. ## System Architecture Requirements A compliant system needs all of the following. Kintsugi maintains this logic for you: Nexus Tracking Engine Continuously monitor sales across all states, compare them to current thresholds, and flag registration before the deadline rather than after. Key features: Real-time sales aggregation by state Threshold monitoring and alerts Registration deadline tracking Historical data analysis Product Taxability Matrix Map SKUs to state-specific tax rules, including exemptions, reduced rates, and price caps. Key features: SKU-to-taxability mapping State-specific product rules Exemption handling Regular rule updates Rate Calculation Engine Resolve rates from precise geocoding of delivery addresses, applying origin and destination logic per state. Key features: Accurate address geocoding Origin vs destination logic 11,000+ jurisdiction support Real-time rate updates Exemption Certificate Management Collect, validate, and store documentation for exempt sales, with workflows for renewal and expiration. Key features: Certificate collection and storage Validation and verification Renewal tracking Audit trail maintenance Marketplace Sales Segregation Separate facilitated from direct sales in reporting, since the two are filed differently and count differently. Key features: Sales channel identification Separate reporting streams Compliance tracking Audit trail maintenance Comprehensive Audit Trails Keep a record of every calculation, including the nexus determination, the taxability decision, the sourcing rule, and any exemption applied. Key features: Complete calculation history Decision point logging Data integrity checks Compliance reporting ## System Architecture Requirements Sales tax obligations move as your business grows, as states change their laws, and as you add sales channels. The five concepts on this page (the four checks, nexus types, sourcing, marketplace facilitator rules, and collection timing) are what let you build systems that scale with the business instead of being rewritten by the next threshold you cross. ## Next Steps Get Started Ready to implement? Start with the Getting Started Guide and the API Reference. Need Help? Questions about your specific use case? Check our Support Center or contact our team. --- # Product Categories How Kintsugi classifies products into categories and subcategories for taxability. Source: https://docs.trykintsugi.com/docs/guides/product-categories Kintsugi classifies every product into a category and subcategory, which together determine how it is taxed across jurisdictions. When you create or update a product, set its subcategory through the category field. See Create a product for the full request, and Get product categories for the complete catalog of values. Search the catalog below to find the right classification for your products. The same data is available programmatically from the Get product categories endpoint. Verified against production Oct 8, 2026 · unchanged since Sep 20, 2026 All Digital Misc Physical Services Showing 1–50 of 700 subcategories Digital Name Description Example Audio Books Recordings of books being read aloud, distributed and consumed in digital formats such as MP3 or proprietary app-based files. Audible audiobooks, MP3 audiobooks, Digital book narrations, Downloadable audiobooks, Streaming audiobooks B2B SaaS Software as a Service designed for business-to-business interactions. Enterprise resource planning (ERP) systems. B2C SaaS Software as a Service aimed at consumers. Personal finance management tools. Canned Educational Software Downloaded B2B Pre-existing software for educational purposes, licensed and delivered to educational institutions or businesses via electronic download. Learning Management Systems (LMS downloaded), Classroom software (institutional download), Training simulation software (B2B ESD), Educational game licenses (bulk download), K-12 curriculum software (download) Canned Non-Educational Software Downloaded B2B General-purpose or business-specific pre-existing software (not primarily educational) licensed and delivered to businesses via electronic download. Office productivity suites (B2B download), Accounting software (download license), CRM software (downloaded), Design software (B2B ESD), Project management tools (download) Canned Software Customization Services to alter or add features to existing prewritten software to meet specific user requirements, without changing core code. Configuring modules, Setting user parameters, Creating report templates, Scripting for integration, Workflow adjustments (COTS) Canned Software Downloaded B2B Pre-existing software acquired by businesses through electronic download, for installation on their own systems. Microsoft Office (volume license download), Adobe Creative Suite (B2B download), Accounting software (ESD), CAD software (download), Server software licenses (downloaded) Canned Software Downloaded B2C Pre-existing software acquired by individual consumers via electronic download for installation on their personal devices. Downloaded games, Productivity apps (download), Utility software (ESD), Mobile apps (purchased/downloaded), Creative software (download license) Canned Software Load & Leave B2B Pre-existing software installed by a vendor directly onto a business customer's hardware, where the vendor does not provide ongoing hosting. On-premise ERP installation, Vendor-installed accounting software, Local server application setup, Desktop productivity suite (on-site install), Machine-specific control software Canned Software Load & Leave B2C Pre-existing software installed by a vendor directly onto an individual consumer's device, where the vendor does not provide ongoing hosting. Home productivity software (installed by tech), Anti-virus setup (on-site), Game installation service (local), Educational software (vendor installed), OS installation (by technician) Canned Software Physical Media B2B Pre-existing software delivered to businesses on tangible storage media such as CDs, DVDs, or USB drives. ERP software (on DVD), CAD/CAM on USB, Boxed office suites, Industry-specific software (CD), Archived software (physical) Canned Software Physical Media B2C Pre-existing software delivered to individual consumers on tangible storage media like CDs, DVDs, or USB drives. Games on DVD, OS on USB drive, Productivity suite (CD-ROM), Educational software (boxed), Tax software (physical media) Canned Software Support - Optional - Load & Leave Updates/Upgrades Only Elective ongoing software updates/upgrades for prewritten software (installed on client hardware by vendor), purchased separately (no other support). Optional COTS upgrades (on-prem), Elective version enhancements (local install), Add-on patch service (local COTS), A la carte prewritten software updates (load & leave), Separately purchased upgrade-only plan (local) Cloud or Remote Storage A service model where digital data is stored on third-party servers and accessed via a network like the internet. Dropbox, Google Drive, iCloud, OneDrive, Amazon S3 (personal/business) Computer Use Access Fee Granting permission or providing means to use a computer workstation, often for a specified period or purpose, including shared/public computers. Internet cafe access, Library computer use, Co-working space hot desk, Kiosk computer session, Pay-per-use terminal Custom Software Downloaded Unique software for specific business needs, delivered to client via electronic download for installation on their systems. Bespoke CRM (downloaded), Custom ERP modules (ESD), Tailored B2B app (download), Proprietary analysis tool (download), Custom e-commerce platform (client-hosted) Custom Software Load & Leave Unique software for specific business needs, installed directly onto client's hardware by vendor, without ongoing vendor hosting. Bespoke on-premise ERP, Custom local database app, Tailored B2B desktop tool, Vendor-installed proprietary software, Client-server custom application Custom Software Physical Media Unique software for specific business needs, delivered to client on tangible storage media like CDs, DVDs, or USB drives. Bespoke software on CD (B2B), Custom application (USB delivery), Tailored ERP system (physical media), Proprietary tool (on DVD for business), Custom database app (physical install media) Custom Software Support - Optional - Electronic Updates/Upgrades Only Elective ongoing electronic delivery of software updates and version upgrades for custom-developed software, purchased separately (no other support). Optional custom SW upgrades (ESD), Elective version enhancements (download), Add-on patch service (custom electronic), A la carte custom software updates, Separately purchased upgrade-only plan Custom Software Support - Optional - Load & Leave Updates/Upgrades Only Elective ongoing software updates/upgrades for custom software (installed on client hardware), purchased separately (no other support). Optional custom SW upgrades (on-prem), Elective version enhancements (local install), Add-on patch service (custom local), A la carte custom software updates (load & leave), Separately purchased upgrade-only plan (local) Custom Software Support - Optional - Updates/Upgrades Only Elective ongoing delivery of software updates and version upgrades for custom-developed software, purchased separately (no other support services). Optional custom SW upgrades, Elective version enhancements, Add-on patch service (custom), A la carte custom software updates, Separately purchased upgrade-only plan (custom) Data Access Fees B2B Charges incurred by businesses for the right to access or retrieve information from databases, platforms, or information services. Database subscription fees (B2B), API access charges, Financial data feed fees, Legal research platform access, Market intelligence report access Data Access Fees B2C Charges incurred by individual consumers for the right to access information from online databases, content platforms, or specialized services. Premium content subscription, Online archive access fees, Genealogy database access, Consumer credit report fees, Pay-per-view data services Data Processing B2B Services provided to businesses involving the collection, manipulation, computation, or organization of data, often automated. B2B payroll processing, Claims processing services, Business data entry, Market research data analysis, Batch data conversion (B2B) Data Processing B2C The collection and manipulation of items of data to produce meaningful information, a general term covering various computation or data organization tasks. Data entry, Data conversion, Information processing, Reports, Statistical analysis Data Processing Electronic Output B2B Services for businesses involving automated or manual processing of data, where the results or output are delivered electronically. Electronic payroll processing, B2B data analysis reports (digital), Digital claims processing, E-statements, Cloud data transformation services Data Processing Electronic Output B2C Services involving manipulation or computation of data where final results are delivered in a digital or electronic format. Digital report, E-statement processing, Online data analysis, Cloud data transformation, Electronic data interchange (EDI) Data Processing Physical Output Services involving manipulation or computation of data where final results are delivered in a tangible, physical format. Printed report, Direct mail processing, Check printing services, Physical document archiving, Label printing services Digital Content and Electronic Product Delivery Services Various digital goods, electronic content, and digital products delivered without physical media or storage devices. Digital product taxability varies significantly by state. digital content downloads, electronic product delivery, digital media content, online digital products, electronic content services Digital Gaming Content and Streaming Services Video games and gaming content delivered through digital download platforms, streaming services, or cloud-based gaming systems. Digital product taxability varies significantly by state. downloadable video games, game streaming services, digital gaming content, online game downloads, cloud gaming subscriptions General Digital Goods - No TPP Any Digital good outside of Kintsugi's defined categories Any Digital good outside of Kintsugi's defined categories Hosted Software with Server Off-Premise B2B Software applications provided to businesses over a network, hosted on servers not located at the customer's premises. Salesforce (CRM), Microsoft 365 (Business), Google Workspace, SAP S/4HANA Cloud, Workday Hosted Software with Server Off-Premise B2C Software applications provided to individual consumers over a network, hosted on servers not located at the consumer's premises. Streaming services (Netflix/Spotify software), Online games (cloud-hosted), Personal cloud storage apps, Web-based email clients, Freemium SaaS (consumer) IaaS B2B Infrastructure as a Service for businesses, offering virtualized computing resources like virtual machines, storage, and networks. AWS EC2 instances (business), Azure Virtual Machines (B2B), Google Compute Engine (enterprise), Cloud storage (business tier), Dedicated hosting (IaaS) IaaS B2C Infrastructure as a Service for individual consumers, offering access to fundamental computing resources like virtual servers or storage. Personal cloud servers (VPS), Consumer cloud storage, Hobbyist virtual machines, Developer sandbox (IaaS), Personal VPN (self-hosted IaaS) Installation/Setup Fees for Hosted Software B2B Charges billed to a business specifically for initial installation, configuration, or setup of an ASP or hosted software service. SaaS onboarding fee, Hosted software setup charge, ASP configuration fee, Cloud application deployment fee, Initial user setup (ASP) Installation/Setup Fees for Hosted Software B2C Charges billed to an individual consumer specifically for initial installation, configuration, or setup of an ASP or hosted software service. Consumer SaaS setup fee, Hosted game installation charge, Personal cloud setup assistance, Streaming service activation fee, Online app configuration support Optional Maintenance Agreement with TPP Sales An elective service contract for future repair or maintenance of Tangible Personal Property (excluding software), purchased with the TPP. Extended hardware warranty, Appliance service plan, Equipment maintenance contract, Furniture protection plan, Vehicle service agreement (optional) PaaS B2B Platform as a Service for businesses, offering a platform for developing, running, and managing applications without managing infrastructure. AWS Elastic Beanstalk (business), Azure App Service (B2B), Google App Engine (enterprise), Heroku (professional tier), Salesforce Platform PaaS B2C Platform as a Service for individual consumers/developers, offering a platform for creating, deploying, and managing personal applications. Free/hobbyist PaaS tiers, Developer PaaS (individual accounts), App building platforms (consumer), Cloud development environments (personal), Serverless functions (personal use) Purchased Digital Games with Permanent Ownership Rights Digitally downloaded video games with permanent ownership rights, offline access, and full game content without subscription requirements. Digital product taxability varies by state. permanently owned digital games, full game downloads, digital game purchases, owned electronic games, permanent digital gaming content Software B2B Computer programs and associated documentation designed for and licensed to businesses for various operational or productivity functions. ERP systems, CRM software, Business analytics tools, Accounting software, Project management software Software B2C Computer programs and associated documentation designed for and licensed to individual consumers for personal use, entertainment, or productivity. Video games, Personal productivity apps, Antivirus software (consumer), Photo editing software (personal), Mobile apps (consumer) Subscription Based Digital Gaming Services Video games accessed through subscription services, streaming platforms, or temporary downloads with limited ownership and access rights. Subscription service taxability varies. gaming subscription services, game streaming access, temporary game downloads, subscription gaming platforms, limited-access digital games System Software Software designed to operate and manage computer hardware and provide a platform for running application software. Operating systems (Windows/macOS/Linux), Device drivers, Utility programs, Firmware, Boot loaders Misc Name Description Example Books - Coupon or Discount Book Bound collections of vouchers or certificates offering discounts, special deals, or free goods/services from various businesses. Entertainment Book, Local coupon books, Restaurant discount books, Travel coupon books, Fundraiser coupon books Credit card processing fees Fees levied by credit card companies for various services. Annual fees, late payment fees. Discount - Manufacturer Rebate A partial refund by a product's manufacturer to customers after purchase, where the initial item sale was taxable. Mail-in rebate, Instant rebate (manufacturer), Cashback offer (mfr.), Product registration rebate, Loyalty rebate (mfr.) Discounts - Cash Payment (vs Credit, Retailer) A price reduction offered by a retailer to customers who pay with cash instead of credit card or other non-cash methods. Cash discount (at gas station), Pay-by-cash savings, Surcharge avoidance (cash), Dual pricing (cash lower), Cash-only price Discounts - Cash (Retailer Early Payment, After POS) A price reduction by a retailer for customer paying an invoice early, applied after the initial point of sale. 2/10 net 30 terms, Prompt payment discount, Early settlement discount, Invoice credit (early pay), Account balance reduction Previous 1 2 … 14 Next --- # Integrating Kintsugi's API How a Kintsugi integration fits together: the four touchpoints, the shared record pattern, checkout, and the transaction record Source: https://docs.trykintsugi.com/docs/guides/integrating-kintsugis-api A Kintsugi integration is smaller than it first looks. Four surfaces in your product each make one call, two of them before a sale and two of them at it. This guide is the map: what talks to what, in what order, and why. For request shapes and endpoint details, each section links down to the guide that covers it. ## Understanding Your Integration Context Three questions shape everything that follows. When do sales tax calculations currently happen in your software? The point in your flow where tax is calculated today is where the estimate call goes tomorrow. Common answers: the checkout page, payment processing, order confirmation, or a subscription billing run. Most integrations land on L2: transaction sync (L1) for compliance, plus the tax engine for live calculation. Build L1 first, then turn on L2 once transactions are flowing. See Planning an Integration for the full model. Are you replacing another tax provider? Map your existing calls to Kintsugi's endpoints before you write anything, and pay attention to where the data models differ rather than where they match. Migrating from Avalara or TaxJar covers the field-level mapping. Are you building from scratch? Start with the transaction record and work backwards. Plan the initial catalog and customer sync as a batch job, design retry and error handling before you need them, and add real-time estimation once the compliance path is solid. ## Core Integration Architecture Every integration comes down to four touchpoints. Nothing else in your stack needs to know Kintsugi exists. In your product The call it makes Customer management Signup, account settings, address edits Create and update customers Reference data Before the sale Product catalog New SKUs, category and description changes Sync products Reference data Before the sale Checkout Cart totals, before payment Estimate tax At the sale Read-only, nothing stored Order processing Once payment clears Create transactions At the sale The record of what you owe What Kintsugi does with it Tax calculation Rates per jurisdiction Compliance tracking Nexus and thresholds Filing preparation Returns per state Build the two reference-data rows first, and note that they fail differently. An unknown product is rejected outright; an unknown customer is accepted, and the sale quietly collects tax that the buyer's exemption should have cleared. ## Customer and Product Records Customers and products are the same problem twice: a record in your system that Kintsugi needs a copy of, keyed on your own identifier. Learn the pattern once, then read the two differences. 1 Something changed on your side A customer signs up or edits an address; a SKU is created or its classification changes. Fire on the write rather than on a nightly job, because tax depends on current data. 2 Does Kintsugi already have it? Look it up by your external_id NO → Create it POST with your external_id in the payload. YES → Update it Same call shape, addressed to the existing record. The lookup is not optional: create is not an upsert, and a duplicate external_id comes back an error rather than replacing the record. Non-2xx otherwise? Back off on 5xx and 429, fix the payload on 4xx. 3 Store the Kintsugi id Keep it on your own record. It is what makes step 2 a lookup instead of a guess, and what transactions reference later. Ready to use in transactions The record can now be named on an estimate or a transaction. Delta · customers Exemptions A separate object on its own schedule, since a buyer often uploads a certificate long after signup. When a certificate arrives Create the exemption Associate it with the customer Effect Later sales to that buyer clear the exemption check instead of collecting tax. Delta · products Classification You pick the category from Kintsugi's taxonomy, and Kintsugi maintains what that category means in each state. Re-send the product when It moves to a different category or subcategory Its tax-exempt flag changes Its name or description is revised Effect The category is what decides taxability per state at calculation time. Jurisdiction rule changes need nothing from you. ## Customer and Product Records Reference by your own IDs. Transactions and estimates name products with external_product_id and customers with an external_id on the customer object, so a stable identifier on your side is what holds the whole integration together. Full request shapes are in Product and Customer Records. Exemptions without a customer record. The exemption delta above assumes a buyer you have on file. For a one-off that belongs to no customer, set exempt: true on the line item instead. For the initial load, create records in batches rather than one at a time, and pause between chunks to stay clear of rate limits. Products never expire, so the catalog can be built well ahead of your first transaction. ## Tax Estimation Integration Tax estimation runs during checkout, where the customer needs an accurate total before they pay. It is usually the most latency-sensitive call in the integration, and the only one that stores nothing. 1 Cart and shipping address Tax needs both. The line items decide taxability, the address decides the rate, and until you have an address there is no estimate to show. 2 Resolve the address first Rates go down to the local level, so an unresolved address gives a rate you cannot defend. Validate, then estimate against the corrected version. INVALID → Surface the correction to the buyer at checkout rather than silently substituting it. They are the only one who knows where the parcel goes. 3 Estimate the tax Send the line items and the resolved address. You get amounts broken out by jurisdiction. 4 Display it and take payment Charge the buyer the estimated tax. Re-estimate if anything in the cart or the address moves between display and payment. Payment clears, so record it Now create the transaction. That is the next section, and it is the only step that changes what you owe. If payment fails, stop. No transaction, no liability: an abandoned checkout leaves nothing behind in Kintsugi. Estimates are free to repeat. Because nothing is recorded, you can call the endpoint every time the cart or the address changes. Debounce address input, and reuse a result while both are unchanged. Sales Tax Calculations covers the request, the response breakdown, and the zero-tax cases. ## Transaction Reporting Integration Once payment clears, the sale becomes a transaction record. This is the call that changes what you owe. What goes in The customer By the id you stored, so exemptions apply. Line items The synced products, with quantities and amounts. Addresses The resolved ship-to, plus where you shipped from. Tax charged What the buyer actually paid, from the estimate. Create the transaction Send it once, keyed on your order id. Same look-up-before-you-write rule as reference data: a repeat external_id is rejected, not merged. What it unlocks Filings The sale lands on the right return for its jurisdiction. Compliance reporting It counts toward nexus thresholds, taxable or not. Sales you never send are sales Kintsugi cannot see. Exempt, zero-tax and marketplace orders all belong here too, because the threshold math needs the whole picture. Reconciling later. The transaction is keyed on your order ID, which is also how you find it again. Syncing Transaction Records covers status transitions and backfill, and Handling Refund Transactions covers credit notes. ## Common Integration Patterns Where you place these four calls depends on what you are building. E-commerce: estimate tax during checkout (L2), create the transaction as soon as payment clears (L1). The most common shape. SaaS and subscriptions: estimate per billing cycle rather than per page view, and create transactions in a batch after the billing run. Marketplaces: calculate per seller, report centrally, and account for marketplace facilitator rules, which decide whether the tax is yours to collect at all. See US Sales Tax for Developers. Whichever shape fits, the ordering constraint is the same: reference data first, then transactions, then live estimation on top. ## Implementation Checklist [ ] API keys created and authentication working end to end [ ] Customers synced, with exemption certificates attached where they exist [ ] Product catalog synced, every item carrying a category and subcategory [ ] Kintsugi IDs stored against your own records [ ] Address validation wired in ahead of estimation [ ] Estimation called at checkout, with retry and graceful degradation [ ] Transactions created on payment, keyed on your order ID [ ] Tested against exempt customers, zero-tax states, and multi-jurisdiction addresses L1 first, then L2. Start with transaction sync: customers, products, and transaction reporting. Once that is stable, add the estimation workflow for real-time checkout totals. See Planning an Integration for the full L1/L2 model. ## Next Steps API Reference Endpoint documentation, request formats, and response structures in the API Reference. SDKs Skip the HTTP layer with our SDKs for Python, TypeScript, Java, PHP, and Ruby. --- # Migrating from Avalara/TaxJar to Kintsugi Map your existing Avalara or TaxJar integration to Kintsugi's endpoints, move your data, and cut over without breaking a filing period Source: https://docs.trykintsugi.com/docs/guides/migrating-from-avalara-taxjar Migrating tax providers is mostly a mapping exercise plus one judgment call. The mapping is small: four concerns, four replacements. The judgment call is how much you want to find out before the old system is switched off. This guide covers both, then the data you need to bring with you. Cut over at the start of a filing period and keep the old system's records. A period split across two engines is the one thing that makes a return genuinely hard to reconcile. ## Understanding Key Differences Three differences change how you build, rather than just which URL you call. Estimating versus recording All three providers can quote tax without recording it, but they express it differently, and this is the difference that shapes your integration. Avalara uses one endpoint for both, switched by DocumentType. A type ending in Order (such as SalesOrder) is a temporary estimate that is not preserved; a type ending in Invoice is a permanent recorded transaction. TaxJar uses two endpoints: POST /v2/taxes calculates and stores nothing, POST /v2/transactions/orders records. Kintsugi also uses two: POST /v1/tax/estimate is read-only, POST /v1/transactions is the record. If you are coming from Avalara, the cleanest mental translation is that your SalesOrder calls become POST /v1/tax/estimate and your SalesInvoice calls become POST /v1/transactions. If you are coming from TaxJar, the two calls you already make map one to one. Data model mapping Kintsugi keys records on your identifiers through external_id, so your own IDs stay the source of truth. Avalara scopes most objects to a company and identifies transactions by a transaction code; TaxJar identifies orders by transaction_id. In all cases, put your existing identifier in Kintsugi's external_id and the reconciliation stays trivial. Product classification Avalara assigns tax codes to items you create under a company. TaxJar has no product records at all: you send a product_tax_code on each line item, chosen from its category list. Kintsugi keeps a product catalog, and each product carries a product_category and a product_subcategory drawn from Kintsugi's own taxonomy. Kintsugi maintains what each category means in every jurisdiction, so you classify once rather than tracking rule changes. ## Understanding Key Differences Tax codes are not portable. An Avalara tax code or a TaxJar product_tax_code has no Kintsugi equivalent, and both category fields are required on every product you create. Budget a classification pass over the catalog as real migration work, not a data copy. ## API Endpoint Mapping Find the call you make today in the left two columns and read across. Avalara TaxJar Kintsugi Tax calculation Quote tax for a cart POST / api/ v2/ transactions/ create DocumentType: SalesOrder POST / v2/ taxes POST / v1/ tax/ estimate All three quote without recording. Avalara does it on the same endpoint that records, switched by document type: a type ending in Order is a temporary estimate that is not preserved. TaxJar and Kintsugi use a separate read-only call. Transaction recording Commit the completed sale POST / api/ v2/ transactions/ create DocumentType: SalesInvoice POST / v2/ transactions/ orders POST / v1/ transactions This is the call that changes your liability, so if you port one thing exactly, port this one. An Avalara type ending in Invoice is the recorded counterpart of the row above. Customer management Buyers and their exemptions POST / api/ v2/ companies/ {companyId}/ customers POST / v2/ customers POST / v1/ customers Key it on the customer id you already use, so the mapping stays obvious during a parallel run. Exemptions are their own object in Kintsugi: POST /v1/exemptions carries the customer_id, and the certificate is an attachment on the exemption. Product management Catalog and tax categories POST / api/ v2/ companies/ {companyId}/ items GET / v2/ categories Read-only list POST / v1/ products TaxJar has no catalog to export: it takes a product_tax_code per line item, so this row is a build rather than a migration. Kintsugi wants its own product_category and product_subcategory, listed by GET /v1/products/categories. ## API Endpoint Mapping Endpoints map cleanly; tax codes do not. Avalara tax codes and TaxJar product_tax_code values have no Kintsugi equivalent, and every product you create needs a product_category and product_subcategory of its own. Budget a classification pass over the catalog before you rely on Kintsugi's rates. Kintsugi paths are verified against the spec that generates this site's API Reference. Competitor paths are current as of publication and taken from Avalara's and TaxJar's own SDKs; check them against your provider's reference before you write the mapping into code, since only they control those. ## Migration Strategy All three approaches end in the same place. They differ in how much you find out before the old system is gone. Option A Big bang Switch everything on one date. How it goes Point every call at Kintsugi Turn the old system off You learn what broke in production Risk Highest Time Shortest Option B Parallel run Run both, compare, then switch. How it goes Call both, charge the old one Diff the amounts, chase the gaps Switch once the diff is explainable Risk Low Time Medium Option C Gradual rollout Move one slice at a time. How it goes Start with one region or state Then one product line Widen until nothing is left Risk Lowest Time Longest Whichever you pick, cut over at the start of a filing period and keep the old system's records. A period split across two engines is the one thing that makes a return hard to reconcile. We recommend the parallel run for anything already in production. It is the only option that lets you compare real amounts on real orders before the old system stops being your safety net, and the cost is a few weeks of double-calling rather than a rewrite. ## What to Bring With You Nexus thresholds are measured over rolling windows, so Kintsugi needs history to tell you where you already have obligations. Starting cold means starting with an empty exposure map. Products and customers Create these first: transactions reference them. Create records in batches rather than one per request, and pause between chunks to stay under rate limits. Store the Kintsugi ID against your own record as you go. Exemption certificates An exemption is its own object. POST /v1/exemptions carries the customer_id it belongs to, along with the exemption type, the effective date, and the buyer's registration details, and the certificate itself is uploaded as an attachment on the exemption. Historical transactions Sync from January 1 of the previous calendar year through today, which covers every rolling window Kintsugi evaluates. For a bulk backfill, CSV upload is usually faster than replaying records through the API, and the uploaded transactions behave identically for nexus tracking and filing preparation. Registrations Record where you are already registered, with the effective date of each permit. Kintsugi calculates tax where a registration is active, so a missing registration reads as a state you do not collect in. Keep external_id values identical to the ones your old integration used. This is what makes a parallel run comparable order by order, and what makes reconciliation possible afterwards. ## Common Migration Challenges Address validation Rates resolve to the local level, so an unresolved address produces a rate you cannot defend. Both providers offer address validation and so does Kintsugi, through POST /v1/address_validation/search and POST /v1/address_validation/suggestions. Solution: Validate the address before you estimate, and estimate against the corrected version. See Sales Tax Calculations for where this sits in the checkout sequence. Exemption certificates Exemption workflows differ more than the endpoints suggest. Kintsugi models an exemption as a separate object owned by a customer rather than a flag on one. Solution: Create the customer first, then the exemption against its customer_id, then attach the certificate. A one-off exemption that belongs to no customer record rides on the line item instead, as exempt: true. Product tax code mapping This is the part of the migration that is not mechanical. Neither provider's codes carry over. Solution: Pull the current taxonomy from GET /v1/products/categories and map your catalog to it rather than hardcoding values. Start with the SKUs that carry the most revenue, since a misclassification there costs the most, and check the result against the old system's rates during a parallel run. Reconciling the two systems During a parallel run you need to know which differences matter. Rounding and jurisdiction rollup differences are expected; a different taxability decision is not. Solution: Diff at the line level rather than the order total, so a difference points at a product or an exemption rather than at a number. Investigate any line where one engine taxes and the other does not before you switch traffic. ## Validation Checklist Before cutover: [ ] Estimation implemented, with address validation ahead of it [ ] Transaction creation implemented, keyed on your existing order IDs [ ] Customers synced, with exemptions and certificates attached [ ] Catalog synced, every product classified against Kintsugi's taxonomy [ ] Historical transactions backfilled through the previous January 1 [ ] Existing registrations recorded with their effective dates [ ] Retry logic, error logging, and rate-limit handling in place [ ] Parallel-run diffs explained at the line level, not just the total [ ] Rollback plan documented, with the old system's records retained ## Post-Migration Stop maintaining tax rules Kintsugi tracks jurisdiction rule changes against your product categories, so a rate or taxability change needs nothing from you. Update a product only when your own classification changes. Estimate freely Because estimates record nothing, you can call the endpoint every time the cart or the address changes, then create the transaction once payment clears. See Integrating Kintsugi's API for where each call belongs. ## Next Steps API Reference Request formats and response structures in the API Reference. Support Migrating a large or unusual integration? Our Support Team has done this before. --- # File Upload Import sales transactions from a CSV file, and the columns the importer reads Source: https://docs.trykintsugi.com/docs/guides/file-upload File upload imports sales transactions from a CSV, which is the fastest way to bring in history when you are onboarding or backfilling a period. Uploaded transactions behave exactly like ones created through the API: they count toward nexus, feed compliance reporting, and land on the right return at filing time. This page is the column reference. Download the template from the app, then use the tables below to fill it in. ## Before You Start Five columns have to be in the file A file missing any of these is rejected before any row is read. The first four need a value on every row. amount is required as a column so that a file without it cannot book every line at 0.00. Every other column can be left out entirely, and the value falls back to the default listed on its row. Leaving one out is not the same as including it and leaving cells blank, which the next two cards cover. transaction_external_id date customer_id product_external_id amount Omitting a column is safe. Blanking a cell is not A default only applies when the column is absent from the file. Once you include a column, the upload validator expects a value in it, and it is stricter than the defaults suggest. Column absent The documented default applies to every row. This is the safe way to skip a column you have no data for. Column present, cell empty Rejected for operation, and a conflict on any transaction-level column where another row of the same transaction does carry a value. Delete the column, or fill it in on every row. One transaction, many rows, identical values A multi-line sale is several rows sharing one transaction_external_id. Only the line item columns are allowed to differ between them. Every transaction-level column you include has to carry the same value on every row, including the addresses, the buyer, the date, status, currency, transaction_type and operation. Filling a column in on the first row and leaving it blank on the rest is the most common way to trip this, because an empty cell counts as a different value. The error names the column and the row it first saw: Inconsistent 'transaction_type': '' vs 'SALE'. ## Before You Start Save the file as text, not as a spreadsheet Format every cell as General before exporting. A cell typed as Date or Number is re-serialized on save, which is the most common reason a file that looks correct fails validation. Postal codes are the other one: a leading zero has to survive the export. Reading the badges Required A value in every row. Conditional Required in a stated case. The rule is on the row. Optional Leave the column out and the default applies. The downloadable template carries two columns the importer does not read. total_amount is ignored because transaction totals come from the line items, so fill in amount and tax_amount per row instead. source is ignored too: each transaction takes its source from the import itself. ## Transaction Columns These describe the sale. Every row of a multi-line sale repeats them, and rows sharing a transaction_external_id are read as line items of one transaction. Identity, type and date 9 columns transaction_external_id Required Your own id for the transaction. Kintsugi keys the record on it. e.g. in_ctvrAUrbiRdSywvQ Alphanumeric, underscores, hyphens, spaces Minimum length 1 Unique per transaction. Rows sharing an id are read as line items of the same sale. related_external_id Conditional The original transaction's id, when this row credits an earlier sale. e.g. PCR_ctvrAUrbiRdSywvQ Required when transaction_type is FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE. A row cannot reference itself. transaction_type Optional What kind of transaction the row represents. e.g. SALE Defaults to SALE Accepted values SALE FULL_CREDIT_NOTE PARTIAL_CREDIT_NOTE TAX_REFUND Both credit-note types require related_external_id. Transaction-level, so every row of a multi-line sale needs the same value. status Optional Where the transaction sits in its lifecycle. e.g. COMMITTED Defaults to COMMITTED Accepted values COMMITTED PENDING CANCELLED FULLY_REFUNDED PARTIALLY_REFUNDED INVALID and ARCHIVED are set by Kintsugi and rejected on import. Transaction-level, so repeat it on every row of a multi-line sale. operation Conditional What the importer should do with the row. e.g. IMPORT Defaults to IMPORT when the column is absent Accepted values IMPORT UPDATE ARCHIVE Required as soon as the column is in the file. A blank cell is rejected outright rather than falling back to IMPORT, so leave the column out or fill it in on every row. date Required When the transaction took place. e.g. 2024-03-23T00:00:00 The template uses YYYY-MM-DDT00:00:00 ## Transaction Columns Format the cell as General. A cell typed as Date is rewritten on save and the row fails. currency Optional Currency for every amount on the row. e.g. USD Any ISO 4217 code Defaults to USD Transaction-level, so repeat it on every row of a multi-line sale. description Optional Free text describing the transaction. e.g. Heirloom Ring Size 8.5 14K Max 1000 characters marketplace Optional Whether a marketplace facilitator collected the tax on this sale. e.g. FALSE TRUE, FALSE, true, false, 1, 0, t, f Defaults to FALSE The buyer 5 columns customer_id Required Your own id for the buyer. Exemptions attach to it. e.g. cust_cCMVtrsfoUV Alphanumeric, underscores, hyphens, spaces Max 100 characters Transaction-level, so every row of a multi-line sale needs the same buyer. customer_name Optional The buyer's full name. e.g. Faith Ortega Max 200 characters customer_email Optional The buyer's email address. e.g. michele45@example.com Any valid email address Max 200 characters customer_company_name Optional The buyer's registered or legal business name. e.g. Example Company Inc. Max 200 characters tax_id Optional The buyer's registration number. Max 100 characters Transaction-level, so every row of a multi-line sale needs the same value. ## Address Columns Addresses decide the rate, so this is the part of the file worth checking twice. A postal code resolves to a local jurisdiction; a state on its own does not. The one rule Every row needs a postal code and a country from one side or the other. Which side is up to you, but you cannot leave both empty. Either ship_to_postal_code + ship_to_country Or bill_to_postal_code + bill_to_country Ship to 7 columns ship_to_country Conditional The recipient's country. e.g. US Max 100 characters Required unless bill_to_postal_code and bill_to_country are both present. A country of PR is read as state PR in the US. ship_to_postal_code Conditional The recipient's postal code. This is what resolves the local rate. e.g. 21830 US: 5-digit ZIP or ZIP+4 Max 50 characters Checked when the country is US or blank. A 4-digit code is accepted and gets its leading zero back, but exporting the column as text is safer. ship_to_state Optional The recipient's state or province. e.g. CO US: 2-letter code or full state name CA: 2-letter province code ship_to_city Optional The recipient's city. e.g. Aurora ship_to_street_line_1 Optional First line of the street address. e.g. 811 Eric Flat Suite 183 Max 1000 characters ship_to_street_line_2 Optional Second line of the street address. e.g. Apt 1606 Max 1000 characters ship_to_phone Optional The recipient's phone number. e.g. +1 665-869-8307 Max 50 characters Bill to 7 columns bill_to_country Conditional The billed party's country. e.g. US Max 100 characters Required unless ship_to_postal_code and ship_to_country are both present. A country of PR is read as state PR in the US. bill_to_postal_code Conditional The billed party's postal code. This is what resolves the local rate. e.g. 21830 ## Address Columns US: 5-digit ZIP or ZIP+4 Max 50 characters Checked when the country is US or blank. A 4-digit code is accepted and gets its leading zero back, but exporting the column as text is safer. bill_to_state Optional The billed party's state or province. e.g. CO US: 2-letter code or full state name CA: 2-letter province code bill_to_city Optional The billed party's city. e.g. Aurora bill_to_street_line_1 Optional First line of the street address. e.g. 811 Eric Flat Suite 183 Max 1000 characters bill_to_street_line_2 Optional Second line of the street address. e.g. Apt 1606 Max 1000 characters bill_to_phone Optional The billed party's phone number. e.g. +1 665-869-8307 Max 50 characters ## Line Item Columns One row per line item. The product columns drive classification, and the money columns are what your filings reconcile against. The product and the money 10 columns product_external_id Required Your own id for the product, usually the SKU. e.g. F80-BRW Alphanumeric, underscores, hyphens, spaces Max 200 characters product_name Optional The product's name. e.g. Product Name 9 product_description Optional The product's description. e.g. Product Description 9 line_item_id Optional Your own id for this line of the transaction. e.g. il_lQtcAcqhLGPQZhSa Max 200 characters amount Conditional What this line came to, after discounts and excluding tax. e.g. 550.51 Commas allowed, no currency symbols A blank cell is 0.00 The column has to be in the file. Transaction totals are summed from these, so this is the figure that has to reconcile. tax_amount Optional Tax collected on this line. e.g. 1.69 Defaults to 0.00 quantity Optional How many units this line covers. e.g. 14 A value below 1 is rejected Defaults to 1 discount_amount Optional Discount applied to this line. e.g. 0.69 Defaults to 0.00 When present it has to be greater than 0 and no more than amount. Since amount is already net of discounts, this column records the discount rather than applying it. exempt Optional Whether this line is exempt from tax. e.g. FALSE TRUE, FALSE, true, false, 1, 0, t, f Defaults to FALSE customer_exempt Optional Whether the buyer holds an exemption covering this sale. e.g. FALSE TRUE, FALSE, true, false, 1, 0, t, f Cannot be TRUE when exempt is also TRUE: the row has to say whether the product or the buyer is the reason. ## Line Item Columns product_name and product_description are optional columns that do real work: Kintsugi classifies the product from them, and classification is what decides taxability per state. A file with bare SKUs imports cleanly and prices badly. ## Importing a Refund A refund is a credit note row that points at the original sale. 1 Mark the row as a credit note Set transaction_type to FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE. That is what makes the next column required. 2 Point it at the original Put the original sale's id in related_external_id, and give the credit note its own transaction_external_id. A row cannot reference itself. PCR_ Credit note ids are conventionally the original id behind a PCR_ prefix, which keeps the pair legible in an export. Set the original's status PARTIALLY_REFUNDED and FULLY_REFUNDED are both accepted values of status, for the original sale's rows. Recording refunds through the API instead? See Handling Refund Transactions. ## After the Upload Kintsugi validates the file before importing any of it, and errors come back per row and per column, so a rejected file tells you which cell to fix rather than just failing. ## Related Resources Getting Started Set up your account and import historical data. Syncing Transaction Records Prefer automation? Sync transactions programmatically instead. Migrating from Avalara or TaxJar Moving providers? CSV upload is usually the fastest way to backfill history. Product Categories How Kintsugi classifies products, which is what the product columns feed. --- # 1. Planning An Integration Understand L1 (transaction sync) and L2 (tax engine) integration levels, and map endpoints to your workflow Source: https://docs.trykintsugi.com/docs/api-guides/planning-an-integration The best integrations are decided before they are coded. Kintsugi uses a two-level integration model: Level 1 (L1) is transaction sync, the foundation for every integration, and Level 2 (L2) adds real-time tax calculation. This guide helps you pick your level, sequence the work, and know which endpoint belongs at which point in your workflow. ## Understanding Integration Types Every integration sends transaction data. What changes is whether Kintsugi also calculates tax at checkout and files on your behalf. LEVEL 1 Baseline Transaction sync Send completed transactions so Kintsugi can determine nexus and prepare filings. Endpoints /v1/products /v1/customers /v1/transactions CALC ONLY No filing Tax calculation Real-time rates at checkout or billing, while you file and remit yourself. Endpoints /v1/tax/estimate /v1/transactions Transaction data is still required. It is how nexus and accurate rates are determined. LEVEL 2 Full Tax + compliance Level 1 plus the tax engine: calculate at checkout and stay filing-ready. Adds to level 1 /v1/tax/estimate Turn on after transaction sync is running. L1 first, always. L1 comes first: In the Kintsugi platform, connections require transaction sync (L1) before the tax engine can be enabled. Establish L1, then enable L2 when you need Kintsugi to calculate and collect tax at checkout. ## Choosing Your Integration Pattern Your choice comes down to two questions: where you are in your compliance lifecycle, and who owns filing. L1: Transaction Sync Only Transaction sync is the foundation. This pattern records completed sales for compliance tracking without real-time tax calculation. You will use: POST /v1/products to sync your product catalog POST /v1/customers (optional) if you track exempt customers POST /v1/transactions to record completed sales Historical data requirement: For transaction sync integrations, send historical transactions covering the previous full calendar year through today. Kintsugi uses that history to determine nexus liability. Without it, we cannot pinpoint when you crossed economic nexus thresholds or calculate your compliance obligations accurately. L1 fits teams moving off manual compliance processes, syncing after the fact from an accounting system, or building an audit trail across existing sales. In platform integrations, this is the Level 1 connection, often labeled "Read Only" or "Compliance" mode. Tax Calculation Only This pattern returns real-time tax rates during checkout without using Kintsugi for filing and remittance. You will use: POST /v1/products to create product records with tax classifications POST /v1/customers (optional) if you sell to exempt entities such as nonprofits or resellers POST /v1/tax/estimate to calculate tax before collecting payment Transaction data is still required: Even when Kintsugi is not handling filing, tax calculation depends on nexus, and Kintsugi determines nexus from your transaction data. Tax calculation without transaction sync works only when nexus and compliance are managed elsewhere and you need Kintsugi purely for rate lookup. ## Choosing Your Integration Pattern When to use this pattern: You are replacing another tax calculation service, your compliance team files separately, or you are a marketplace calculating tax for sellers without owning their compliance. The tax estimate endpoint returns tax amounts, rates, and a per-line-item tax breakdown without creating a transaction record. That makes it a natural fit for shopping carts, subscription billing platforms, and point-of-sale systems. L2: Transaction Sync + Tax Calculation (Both) Most production integrations use both: L1 for compliance plus the tax engine for checkout. Calculate tax during checkout for accurate pricing, then sync the completed transaction for compliance tracking. In platform integrations, L2 is the Level 2 connection, often labeled "Tax Engine" mode, enabled after L1 is established. Choose Your Path Two questions decide the integration. Start at the left. Q1 Do you need compliance tracking? Nexus monitoring, registrations, filings YES Kintsugi tracks and files L1 Start with transaction sync Required first. Products, customers and transactions. then Q2 Calculate tax at checkout? YES → Level 2: tax + compliance Add the tax engine on top of L1. NO → Level 1 only Sync now, enable L2 whenever you're ready. NO You file and remit yourself Q2 Need tax calculation only? YES → Tax calculation only Plus transaction data, so nexus stays accurate. NO → Talk through the use case Reach out and we'll scope the integration with you. ## Historical Transaction Requirements If you are building an L1 or L2 integration, or using tax calculation with Kintsugi-managed nexus, send historical transaction data covering the previous full calendar year through today. Why Historical Data Matters Kintsugi determines nexus liability by analyzing your sales volume and transaction counts across jurisdictions. Economic nexus thresholds (commonly $100,000 in sales or 200 transactions) are evaluated over a rolling 12-month period or a full calendar year, depending on the state. Some states use their own fiscal year: New York, for example, runs March 1st through the last day of February. Without history, we cannot: Determine when you crossed nexus thresholds Calculate accurate compliance start dates Prepare accurate tax filings Track nexus status changes over time What if I don't have historical data? Kintsugi will still track your future transactions and calculate nexus going forward. You may need to set registration effective dates and nexus status manually from your own records. Contact our support team to walk through your situation. What date range should I sync? Sync from January 1st of the previous calendar year through today. Integrating in March 2026, for example, means syncing January 1, 2025 through March 2026. That gives nexus calculations a complete data set. Do I need to sync transactions for tax calculation only? In most cases, yes. Even when Kintsugi is not handling filing and remittance, tax calculation depends on nexus status, and Kintsugi derives nexus from your transaction data. The one exception is when you manage nexus and compliance entirely elsewhere and need Kintsugi only for rate lookup. ## When to Use Each Endpoint Knowing where each endpoint belongs in your workflow prevents wasted API calls and keeps your data consistent. Tax Estimate Endpoint ( POST /v1/tax/estimate) Call this endpoint during checkout or billing, before payment is collected. Typical integration points: Shopping cart pages: When customers review their order before payment Checkout flows: After address entry, before payment processing Subscription billing: When calculating tax for recurring charges Quote generation: When quoting a price to a customer The estimate endpoint does not create a transaction record, so you can call it as often as customers change their cart or address. Best practice: Call /v1/tax/estimate after address validation and before final payment processing. You get tax for a verified address and an accurate total to show the customer. Transaction Sync Endpoint ( POST /v1/transactions) Call this endpoint once a sale is complete and payment is confirmed. Typical integration points: Order confirmation: After payment succeeds and the order is finalized Invoice creation: When generating invoices for completed sales Daily batch jobs: Syncing from your order management system Webhook handlers: Processing order completion events from e-commerce platforms Transaction records should reflect real completed sales, not estimates or open carts. Send type: "SALE" and status: "COMMITTED" so the transaction counts toward compliance calculations. Do not sync open carts: Sync only after payment is confirmed. If your system creates orders before payment, you can record them with status: "PENDING" and update to COMMITTED once payment clears. Set status: "CANCELLED" for orders that fall through. Only committed transactions feed nexus calculations and filings. ## Integration Setup Workflow Your setup sequence depends on your integration type, but the shape is consistent. Step 1: Create Product Records Every integration starts with product records. Products carry the tax classification that decides whether an item is taxable in a given jurisdiction. Create products before you calculate tax or sync transactions. See the Product & Customer Records guide for product creation workflows. Step 2: Create Customer Records (If Needed) Customer records are required only when you sell to exempt entities such as nonprofits, resellers, or government agencies. If you sell to ordinary consumers, skip this step and pass customer details inline on the transaction. See the Product & Customer Records guide for when and how to create customer records. Step 3: Historical Transaction Sync (L1, L2, or Tax Calculation) If you use transaction sync (L1 or L2) or tax calculation with Kintsugi-managed nexus, import historical transactions from the previous calendar year. This is a one-time bulk operation that sets your nexus tracking baseline. See the Syncing Transaction Records guide for bulk import strategy. Step 4: Real-Time Integration With setup complete, wire the right endpoints into your live workflows: L1 (transaction sync only): /v1/transactions on order completion Tax calculation only: /v1/tax/estimate in checkout, plus transaction sync for nexus L2 (both): /v1/tax/estimate at checkout and /v1/transactions after payment confirmation ## Common Integration Patterns Different business models call for different approaches. E-Commerce Platforms Most e-commerce platforms land on L2. Start with L1 to sync completed orders for compliance, then enable the tax engine to price tax during checkout and show customers an accurate total before they pay. A Level 2 checkout makes two Kintsugi calls: one to quote tax, one to record the sale. 1 Customer adds items to cart Your storefront, no Kintsugi call yet. 2 Customer enters shipping address Destination determines the rate. 3 Calculate tax POST /v1/tax/estimate Returns tax amount 4 Display total with tax Show the quoted amount before payment. 5 Process payment Declined? Return the customer to the cart. No transaction is recorded, so nothing to reverse in Kintsugi. 6 Record the transaction POST /v1/transactions Only after payment succeeds 7 Order complete The sale now counts toward nexus and appears in filings. Subscription Billing Platforms Subscription platforms typically run L2: calculate tax when a subscription is created and at each renewal, then sync the transaction per billing cycle for compliance. Marketplace Platforms Marketplaces often price tax for sellers without owning seller compliance. Tax calculation only fits well here, with sellers handling their own transaction sync. Transaction data is still required wherever Kintsugi manages nexus. Accounting System Integrations Accounting integrations usually start at L1: sync invoices and completed sales for compliance tracking, with no real-time calculation. Enable the tax engine (L2) later if the need appears. ## Next Steps Once you have chosen your integration type: Set up authentication: Every request needs your x-api-key and x-organization-id headers. See Creating and Managing API Keys for details. Create product records: Start with your catalog. See the Product & Customer Records guide. Plan your data sync: If you need transaction sync, plan the historical import. See the Syncing Transaction Records guide. Build your integration: Wire the endpoints into the workflows described above. For endpoint-level detail, see the API Reference. --- # 2. Product & Customer Records Create and manage product and customer records that power tax calculations and compliance tracking Source: https://docs.trykintsugi.com/docs/api-guides/product-customer-records Product and customer records are the foundation of every Kintsugi integration. Products carry the tax classification that decides whether an item is taxable in a given jurisdiction. Customer records anchor exemptions to the buyers who hold them. This guide covers when to create each record, how to reference them, and how to verify they landed. ## Understanding Product Records A product record maps one of your catalog items to a Kintsugi tax classification. Each record holds: Your identifier for the item ( external_id) plus its name and description A tax classification ( product_category and product_subcategory) A tax-exempt flag ( tax_exempt) An approval status ( status) Transactions and tax estimates reference products by external_product_id. Kintsugi reads the matching product's classification to decide whether the item is taxable where your customer is. Create products first: Transactions reference products by external_product_id, so create your catalog before calling /v1/transactions. Tax estimates can classify an item inline by sending product_category and product_subcategory alongside the external_product_id, which creates the product on the fly, but a pre-built catalog keeps classification consistent across every call. ## Creating Product Records Create products with POST /v1/products. Required Fields external_id: Your unique identifier for the product (for example, "SKU-12345") name: Product name product_category: High-level category, such as Physical, Digital, or Service product_subcategory: Subcategory within that category, such as General Clothing or B2B SaaS tax_exempt: Whether the product is exempt from tax Optional Fields description: Product description status: Approval status ( APPROVED, PARTIALLY_APPROVED, or PENDING). Defaults to APPROVED source: Where the record originated. Defaults to OTHER Pull the category list from the API: Supported categories and subcategories are returned by GET /v1/products/categories. Read from that endpoint rather than hardcoding values, so your mapping stays valid as the taxonomy grows. What if I have thousands of products? Create them in batches. POST /v1/products takes one product per request, so send them in chunks of 50 to 100 concurrent requests and pause between chunks to stay clear of rate limits. Products never expire, so you can build the catalog well ahead of your first transaction. Do I need to update products if tax rules change? No. Kintsugi tracks jurisdiction rule changes for you, and product records stay as they are. Update a product only when your own classification changes, for example when an item moves from one category or subcategory to another. Can I delete products? The API has no delete endpoint for products, by design. Kintsugi keeps product history so past transactions stay auditable. To retire an item, stop referencing it in new transactions and leave the record in place. ## Verifying Product Records Confirm your catalog with GET /v1/products. The endpoint is paginated ( page, and size up to 100) and supports: query for a free-text search across name and other details product_category__in and product_subcategory__in to check classification coverage status__in to surface anything still PENDING source__in and order_by to scope and sort results To fetch one product directly, use GET /v1/products/{product_id} with the Kintsugi product ID returned at creation. Store the Kintsugi product ID: GET /v1/products searches by free text, not by exact external_id. Saving the id from your create response gives you a precise lookup later. Product Creation Workflow Products carry the tax category that drives every rate lookup. Create them before the first transaction. 1 Prepare and validate the payload Five fields are required before you send anything. external_id name product_category product_subcategory tax_exempt Pull the category and subcategory values from GET /v1/products/categories rather than hardcoding them. 2 Create the product POST /v1/products Returns the product id Non-2xx? See error handling below. 3 Verify it exists GET /v1/products Optional, recommended 4 Product is ready for tax calculations Reference it by external_id in estimates and transactions. ## Understanding Customer Records A customer record identifies a buyer and gives exemptions something to attach to. Create customer records when you sell to: Nonprofit organizations Government agencies Resellers holding valid exemption certificates Any other exempt entity Exemptions themselves are separate records created against a customer through the exemptions API. Once an exemption is on file, Kintsugi applies it when that customer appears on a tax estimate or transaction. When you don't need customer records: Selling only to ordinary consumers? Skip customer creation and pass the buyer's details inline on the transaction's customer object. ## Creating Customer Records Create customers with POST /v1/customers. The API accepts a partial record, so send everything you have; in practice, exemption matching and address-based tax work depend on the fields below. Fields to Send external_id: Your unique identifier for the customer (for example, "CUST-789") name: Customer or business name email: Customer email address Address fields: street_1, street_2, city, county, state, postal_code, and country (ISO 3166-1 alpha-2), or a single full_address string in their place Other Optional Fields phone: Contact number status: ACTIVE or INACTIVE. Defaults to ACTIVE registration_number: The customer's registration number customer_tax_registrations: The customer's tax registrations, where you track them Customer Addresses A customer record carries one address, written as flat fields on the record itself rather than as a list. That address identifies the customer; it does not decide the tax jurisdiction on its own. Jurisdiction comes from the addresses on the transaction or estimate, where each entry has a type of SHIP_TO, BILL_TO, SHIP_FROM, or BILL_FROM. The SHIP_TO address determines which rates apply, and Kintsugi falls back to BILL_TO when no SHIP_TO address is present. Adding Exemptions With the customer created, attach the exemption using POST /v1/exemptions. That request needs: exemption_type: The kind of exemption, such as wholesale or resale start_date: When the exemption takes effect ( YYYY-MM-DD) customer_id: The Kintsugi customer ID from your create response FEIN: Federal Employer Identification Number sales_tax_id: Sales tax ID on the certificate status: Exemption status, for example ACTIVE ## Creating Customer Records Add jurisdiction, country_code, end_date, and reseller where they apply, and upload the certificate itself with POST /v1/exemptions/{exemption_id}/attachments. ## Verifying Customer Records Confirm your customers with GET /v1/customers. The endpoint is paginated ( page, and size up to 100) and supports: search_query for a free-text search across name and other details country and state to scope results by geography source__in and order_by to filter and sort For an exact lookup, use GET /v1/customers/external/{external_id} with your own identifier, or GET /v1/customers/{customer_id} with the Kintsugi customer ID. Customer Creation Workflow A customer record is only required when exemptions are involved. Everyone else can be passed inline. Q Does this customer hold an exemption? NO Skip the customer record Pass customer data inline on the transaction The address on the transaction is enough to source the sale. Nothing else to create. YES Create the record so exemptions can attach to it 1 Prepare and validate the payload The API accepts a partial record, so send everything you have. These are what exemption matching and address-based rates depend on. external_id name email Plus the address: street_1, city, state, postal_code and country, or a single full_address in their place. Run it through address validation first, since a bad address means a wrong rate. 2 Create the customer POST /v1/customers Returns the customer id Non-2xx? See error handling below. 3 Attach the exemption One per jurisdiction the customer is exempt in. Without an exemption on file, tax is still charged. POST /v1/exemptions Needs the customer id Then upload the certificate itself to POST /v1/exemptions/{exemption_id}/attachments. 4 Verify it exists GET /v1/customers Optional, recommended 5 Customer is ready for transactions Exemptions apply automatically on every matching sale. ## Using Products and Customers in Transactions With records in place, reference them from your tax estimates and transactions. Referencing Products Each line item points at a product through external_product_id: { "transaction_items": [ { "external_id": "ITEM-001", "date": "2026-01-15T10:00:00Z", "external_product_id": "PROD-12345", "quantity": 2, "amount": 100.00 } ] } Kintsugi resolves the product and applies its classification to calculate tax. Referencing Customers Transactions and estimates carry the buyer on a customer object. Send your external_id there to match an existing record: { "customer": { "external_id": "CUST-789", "name": "Northwind Nonprofit", "email": "ap@example.org" }, "transaction_items": [], "addresses": [] } When the external_id matches a customer on file, Kintsugi applies that customer's exemptions. If no record matches, the details you send are used for the transaction and the exemption lookup finds nothing to apply. You can also reference a customer on a transaction by their Kintsugi ID using customer_id. ## Updating Product and Customer Records Update with PUT /v1/products/{product_id} and PUT /v1/customers/{customer_id}. Typical cases: Products: Reclassifying category or subcategory, changing the tax_exempt flag, revising name or description Customers: Correcting an address, updating contact details, changing status Product updates are full replacements: PUT /v1/products/{product_id} requires name, product_category, product_subcategory, and tax_exempt on every call. Send the complete record, not just the fields you are changing. Updates do not rewrite history. Only future tax calculations and transactions use the new values. When to update versus create new: If an item's tax treatment fundamentally changes, for example moving from physical goods to a digital download, create a new product under a new external_id instead of editing the old one. That keeps a clean audit trail of when the classification changed. ## Best Practices Product Management Build the catalog first: Have products in place before you wire up tax calculation or transaction sync Read categories from the API: Source values from GET /v1/products/categories instead of hardcoding them Use consistent external IDs: Pick one convention, such as always the SKU, and hold it across every system Batch creation: Send products in chunks to stay within rate limits Verify before you rely on them: Confirm products exist before referencing them in transactions Customer Management Create records where exemptions live: Ordinary consumers can travel inline on the transaction Validate addresses: Run addresses through the address validation API before you save them Store Kintsugi customer IDs: You need the id to attach exemptions and for exact lookups Handle exemptions as a second step: Create the customer, then attach exemptions through the exemptions API ## Error Handling Same policy for products and customers. Read the response, then decide whether the failure is worth retrying. RETRYABLE 5xx · 429 Back off, then re-send Wait with exponential backoff, then send the identical payload. A 5xx can still leave the record written, so look it up before re-sending: external_id has to stay unique, and a blind retry can come back as a duplicate instead. NOT RETRYABLE 4xx Fix the data, then re-send The response body names the offending field. Correct it, re-validate, and start again from step 1. Retrying unchanged will fail the same way. Cap retries. Three attempts is plenty. After that, log the payload and the response and surface it for a human rather than looping. Common Failures What actually goes wrong when creating products and customers: Duplicate external_id: Look the record up before creating it Invalid category or subcategory: Match values to GET /v1/products/categories Missing required fields: Products need external_id, name, product_category, product_subcategory, and tax_exempt Invalid address: Validate addresses before saving them Missing authentication headers: Every request needs both x-api-key and x-organization-id For the full status-code reference and retry code samples, see the Error Handling guide. ## Integration Checklist Before you wire up tax calculation or transaction sync: [ ] Created product records for every item in your catalog [ ] Verified products exist and carry the classification you expect [ ] Created customer records for exempt entities (if applicable) [ ] Attached exemptions to those customers and uploaded certificates (if applicable) [ ] Tested product lookup in a sample tax estimate request [ ] Tested customer lookup in a sample transaction request ## Next Steps With products and customers in place: Start calculating tax: Reference products in /v1/tax/estimate requests. See the Sales Tax Calculations guide. Sync transactions: Reference products and customers in /v1/transactions requests. See the Syncing Transaction Records guide. Handle updates: Set up workflows to push catalog and customer changes through to Kintsugi. For endpoint-level detail, see: Create Product Get Products Get Product Categories Create Customer Get Customers Create Exemption --- # 3. Syncing Transaction Records Sync completed sales transactions to Kintsugi for compliance tracking and nexus determination Source: https://docs.trykintsugi.com/docs/api-guides/syncing-transaction-records Transaction sync (also called Level 1 or L1) creates the permanent record of your completed sales in Kintsugi. Those records drive nexus tracking, compliance reporting, and filing preparation. Every Kintsugi integration rests on them, whether you run L1 only, tax calculation only, or L2. This guide covers when to sync, how to shape the payload, and how to run a clean bulk import. ## Understanding Transaction Sync Each transaction represents one completed sale, carrying: Transaction details: date, type, amount, currency, status Line items that reference your products Customer details and addresses Tax amounts, when tax was calculated at checkout Kintsugi uses those records to: Determine economic nexus by tracking sales volume and transaction counts by jurisdiction Prepare filings by aggregating transactions per jurisdiction Maintain an audit trail for compliance Track refunds and credit notes against original sales Transaction sync (L1) is the foundation: /v1/transactions records sales; it does not calculate tax. With the tax engine (L2) enabled, Kintsugi prices tax at checkout and you still sync the completed transaction afterward. Tax calculation without transaction sync is only viable when nexus and compliance are managed elsewhere. See Planning an Integration. ## When to Sync Transactions Sync once the sale is complete and payment is confirmed. The cadence is yours to choose. Real-Time Sync Sync immediately after order completion when you have: High-volume e-commerce A requirement for immediate compliance visibility Real-time reporting needs Real-time sync keeps your nexus status and compliance data current to the minute. Batch Sync Sync in batches when you have: An accounting system integration Periodic order exports A daily or weekly operational rhythm Batching cuts request volume and suits systems that already process orders in groups. Batch cadence: Sync at least daily. Economic nexus thresholds are evaluated over a rolling 12-month period or a calendar year depending on the state, so a daily rhythm keeps your tracking gap-free. ## Transaction Statuses Status is the only thing that decides whether a transaction affects your compliance position. COMMITTED Counts toward nexus thresholds at its full amount and appears in filing preparation. The end state for a sale that stands. PENDING Stored, but excluded from both. A holding state, not an end state. CANCELLED Excluded permanently, and kept on record so the order history stays complete. FULLY_REFUNDED The sale was refunded in full, so it nets to nothing for compliance. Kintsugi sets this as credit notes cover the full amount, and you can send it yourself on a historical import that is already refunded. PARTIALLY_REFUNDED Part of the sale was refunded. It still counts, reduced by the credited amount. Set the same two ways as FULLY_REFUNDED. COMMITTED is the default when you omit status. Every value above is accepted on both create and update, refunded states included, so a historical import can land a sale directly in its end state instead of replaying the sale and then its credit note. Kintsugi also uses INVALID and ARCHIVED for records it sets aside itself; you would not normally send either. status and refund_status are different fields: status is the transaction's overall state, and it is what compliance reads. refund_status is a narrower field that only ever holds FULLY_REFUNDED or PARTIALLY_REFUNDED, and Kintsugi maintains it as credit notes arrive. Both are writable on create and update; see Handling Refund Transactions for how credit notes drive them. Only COMMITTED transactions count in full: Transactions with status: "COMMITTED" feed nexus calculations and filing preparation at their full amount. PENDING transactions are stored but sit out of compliance processing until they are committed, and refunded states count net of what was credited. ## Choosing a Sync Pattern There are two ways to get a sale into Kintsugi, and they are alternatives rather than consecutive steps. The difference is when you first call Kintsugi, before the payment clears or after. Both end in the same place. PATTERN A Simplest Sync after payment One call, sent once the payment clears. Failed orders never reach Kintsugi at all. Best when Payment settles in one step, at checkout. Nothing to reconcile later. PATTERN B Full lifecycle Create pending, then update Record the sale immediately as PENDING, then commit or cancel it on the outcome. Best when Payment is asynchronous: invoices, terms, authorizations captured later. Pattern A: Sync After Payment The payment gate comes first. Nothing is sent until you know the order is real. 1 Order placed, payment processes Entirely in your system. No Kintsugi call yet. DECLINED → Stop. Don't sync. There is no transaction in Kintsugi, so there is nothing to cancel or reverse. 2 Assemble and check the payload type customer addresses transaction_items Every product must already exist as a product record, and every address must validate. Both are the usual cause of a rejected sync. 3 Send the transaction, already committed POST /v1/transactions status: COMMITTED COMMITTED is the default, so omitting status lands here too. Send it anyway: it makes the intent explicit at the call site. 4 Synced and counting toward nexus Nothing further to do. The sale is filing-ready. Pattern B: Create Pending, Then Update Two calls. The first records the sale, the second resolves it. Status is what makes it count. 1 Record the sale up front POST /v1/transactions status: PENDING ## Choosing a Sync Pattern Same payload as pattern A, but status is not optional here: it defaults to COMMITTED, so leaving it out commits the sale immediately. A pending transaction is stored but excluded from nexus and filings. 2 Wait for the payment outcome Minutes or weeks. The transaction sits in PENDING until you know. 3 Update the status to match PUT /v1/transactions/{transaction_id} Kintsugi id, not external_id PAID → COMMITTED Now counted in nexus calculations and pulled into filing preparation. DECLINED → CANCELLED Excluded from compliance tracking. Keep the record; don't delete it. This is a full replace, not a patch: external_id, date, customer, addresses and transaction_items all have to come back with the new status. Store the id from step 1, or resolve it with GET /v1/transactions/external/{external_id}. A transaction left in PENDING is invisible to nexus and filings. If step 3 never runs, the sale silently goes unreported. Poll GET /v1/transactions?status=PENDING to catch records that have gone stale. Beyond payment confirmation, creating as PENDING is also how you reserve an external_id before an order is final. Cancel rather than commit when the order is voided, payment fails and will not be retried, or the sale falls through: cancelled transactions stay on record for audit purposes and are excluded from nexus calculations and filings. ## Creating Transactions Create transactions with POST /v1/transactions, one transaction per request. Required Fields external_id: Your unique identifier for the transaction (for example, "TXN-2026-001") date: Transaction date and time in ISO 8601 format type: Transaction type. Use SALE for sales currency: ISO 4217 currency code, for example USD customer: The buyer, either matched by external_id or described inline addresses: At least one address transaction_items: The line items sold Recommended Fields status: Defaults to COMMITTED. Send it explicitly when you sync orders before payment clears total_amount: Defaults to 0.00, so send the real total source: Where the sale originated, for example API. Defaults to OTHER description: A human-readable label that pays for itself when reconciling Your organization is read from the header: x-organization-id scopes every request, and the organization_id field in the request body is deprecated. Send both authentication headers, x-api-key and x-organization-id, and let the body describe the sale. Transaction Items Each line item points at a product: external_product_id (required): The product's identifier in your system date (required): Item date, normally matching the transaction date external_id: Your identifier for the line item quantity: Defaults to 1.0 amount: Line item subtotal. Defaults to 0.00, so send the real figure Addresses Every address entry needs a type of SHIP_TO, BILL_TO, SHIP_FROM, or BILL_FROM, plus the address itself: street_1, street_2, city, county, state, postal_code, and country (ISO 3166-1 alpha-2). A single full_address string can stand in for the components. The SHIP_TO address sets the tax jurisdiction. When no SHIP_TO address is present, Kintsugi falls back to BILL_TO. ## Creating Transactions Transactions are processed asynchronously: POST /v1/transactions returns 202 Accepted with the queued record and a processing_status of QUEUED. A 202 means Kintsugi accepted the transaction, not that nexus and tax processing have finished. Read processing_status back through the GET endpoints to confirm it completed. ## Historical Transaction Sync Transaction sync integrations start with a historical import covering the previous full calendar year through today. This one-time operation sets your nexus tracking baseline. Historical Data Requirements Cover: Start date: January 1st of the previous calendar year End date: Today, or your integration start date Scope: All completed sales in that window What if I don't have complete historical data? Send what you have. Kintsugi tracks nexus forward from the data it receives. You may need to set registration effective dates manually where records are missing. Contact support and we will work through it with you. Should I sync cancelled or refunded transactions? Yes, sync everything. Mark voided sales with status: "CANCELLED", and record refunds as credit notes against the original transaction. The result is a complete, defensible audit trail. How do I handle large historical imports? Chunk by date range and send transactions in groups of 50 to 100 concurrent requests, pausing between chunks. Because processing is asynchronous, you can move large volumes without long-running requests. If you would rather not build an importer, CSV file upload covers the same ground. Bulk Import Strategy For large historical imports: Chunk by date range: Work month by month or week by week Batch your requests: The endpoint takes one transaction per call, so send 50 to 100 concurrently and pause between chunks Handle errors deliberately: Log failures, fix the data, replay the batch Verify completion: Reconcile with GET /v1/transactions by date range against your source-of-truth counts Order matters: Import oldest first. Nexus is evaluated against transaction dates, and a chronological import keeps threshold crossings accurate as they are calculated. ## Verifying Transactions Read transactions back with GET /v1/transactions. The endpoint is paginated ( page, and size up to 100) and supports: date__gte and date__lte for date ranges status and processing_status__in to separate committed, pending, and still-processing records search_query for a free-text search that covers your order identifiers transaction_type, state, state_code, country, marketplace, exempt__in, and filing_id to narrow further order_by to sort, prefixed with - for descending, for example -date For exact lookups, use GET /v1/transactions/external/{external_id} with your own identifier, or GET /v1/transactions/{transaction_id} with the Kintsugi transaction ID. ## Updating Transactions Update with PUT /v1/transactions/{transaction_id}. Typical cases: Status changes: Moving PENDING to COMMITTED after payment confirmation Address corrections: Fixing incomplete or invalid addresses Amount adjustments: Correcting totals or line items Filed transactions lock: Once a transaction is included in a filing it is locked and can no longer be updated. Make corrections before the filing period closes. ## Best Practices Data Quality Use consistent external IDs: One convention across every system Validate before syncing: Confirm products exist and addresses are valid first Send complete data: Fields with defaults, especially total_amount and item amount, will silently post as zero if you omit them Get timezones right: Use ISO 8601 with timezone information on transaction dates Sync Timing Sync after payment confirmation: Only committed transactions count toward compliance Sync in chronological order: Oldest first, especially on historical imports Handle duplicates: Look up the transaction before creating it to avoid duplicate external_id errors Monitor the pipeline: Track both request success and processing_status on the records you create Error Handling Common failures when syncing transactions: Product not found: Create products before referencing them Duplicate external_id: Check whether the transaction already exists Invalid address: Validate addresses before syncing Missing required fields: type and customer are required alongside external_id, date, currency, addresses, and transaction_items Missing authentication headers: Every request needs both x-api-key and x-organization-id See the Error Handling guide for detailed strategies. ## Integration Patterns E-Commerce Platforms E-commerce platforms typically sync the moment an order completes: Order is placed and payment confirmed Create the transaction with type: "SALE" and status: "COMMITTED" Include every line item with its product reference Include the shipping address so the jurisdiction resolves correctly Subscription Platforms Subscription platforms sync per billing cycle: The subscription invoice is generated Create the transaction once the invoice is paid Reference the subscription product and the customer Include the billing address Accounting Systems Accounting systems sync in batches: Export completed invoices and sales Create transactions with type: "SALE" and status: "COMMITTED" Process in date order, oldest first Retry failures after correcting the underlying data ## Next Steps With transaction sync running: Handle refunds: Record credit notes against original sales. See the Handling Refund Transactions guide. Query transactions: Use the GET endpoints for reporting and reconciliation. See the Get Transactions API reference. Monitor sync health: Watch request success rates and processing_status so failures surface early. For endpoint-level detail, see: Create Transaction Get Transactions Get Transaction by External ID Update Transaction --- # 4. Handling Refund Transactions Create credit notes and refund records that properly track refunds for compliance and filing preparation Source: https://docs.trykintsugi.com/docs/api-guides/handling-refund-transactions Refunds change what you owe, so they need to reach Kintsugi as deliberately as the sales they reverse. A credit note records a refund against the original transaction, keeping your filings anchored to net sales rather than gross. This guide covers when to create credit notes, how to shape them, and how full and partial refunds behave. ## Understanding Credit Notes A credit note in Kintsugi represents a refund, return, or adjustment against an original sale. Each credit note: Is created against the original transaction, which Kintsugi records on the credit note's related_to field Carries the amount being credited on total_amount and on each line item Updates the original transaction's refund status Offsets the original sale in compliance calculations The outcome is filings that reflect what you actually kept. Credit notes are transactions: Credit notes are transaction records with their own endpoint. Create them with POST /v1/transactions/{original_transaction_id}/credit_notes, and Kintsugi records them with a type of FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE. ## When to Create Credit Notes Create a credit note whenever you refund, accept a return, or adjust a completed sale: Product returns: The customer sends items back Service cancellations: The customer cancels and is refunded Billing adjustments: You correct an overcharge or an error Partial refunds: You refund specific line items rather than the whole order Which sales can be credited: A sale can carry a credit note while its status is PENDING, COMMITTED, or PARTIALLY_REFUNDED. A CANCELLED sale, an already FULLY_REFUNDED one, or a record Kintsugi has set aside is rejected with 400. A cancelled order needs no credit note in the first place. ## Creating Credit Notes Create credit notes with POST /v1/transactions/{original_transaction_id}/credit_notes. The path parameter is the original transaction's Kintsugi transaction ID, not your external_id. Required Fields external_id: Your unique identifier for the credit note (for example, "CN-2026-001") date: Credit note date, normally the refund date, in ISO 8601 format status: PENDING, COMMITTED, or CANCELLED total_amount: The amount being credited currency: ISO 4217 currency code, for example USD transaction_items: The line items being credited Optional Fields description: The reason for the refund, which is worth sending on every credit note addresses: Addresses for the credit note, where they differ from the original taxable_amount, tax_amount_imported, tax_rate_imported: Tax figures you already calculated elsewhere Credit Note Line Items Each item mirrors a line from the original sale and requires: external_id: Your identifier for the credit note line date: Item date external_product_id: The same product identifier used on the original line quantity: Units being credited amount: Value being credited for that line Either sign works: Send total_amount and item amount positive or negative as you prefer. Kintsugi normalizes credit note amounts to negative on write, so the stored record is consistent either way. Quantities stay positive. The Create Credit Note reference carries a complete worked example. Credit Note Workflow You never edit the original sale. You attach a credit note to it, and Kintsugi adjusts your liability from there. 1 Find the original transaction GET /v1/transactions/external/{external_id} Look it up by your own id ## Creating Credit Notes The credit note endpoint takes Kintsugi's transaction id, not your external_id, so you need this unless you stored the id when you synced the sale. 2 Check the sale can be credited A sale can carry a credit note while it is pending, committed, or already partially refunded. REJECTED → A cancelled sale, an already fully refunded one, or anything Kintsugi has set aside comes back 400. A cancelled sale needs no refund in the first place. 3 Build the credit note Match the line items you are crediting to the items on the original sale, then total them. CHECK Two independent caps apply, and both are the remaining balance rather than the original figure. Validate before sending: an over-refund is rejected, not trimmed to fit. 4 Create the credit note POST /v1/transactions/{transaction_id}/credit_notes Returns the credit note Non-2xx? Same retry policy as product and customer creation: back off on 5xx and 429, fix the payload on 4xx. 5 Refund recorded Once the credit note is COMMITTED, the original sale's refund_status updates itself and your liability drops by the credited tax. ## Full Versus Partial Refunds Kintsugi reads the amounts and classifies the refund for you. Full Refunds When the credit note covers the full original amount, Kintsugi records: Credit note type: "FULL_CREDIT_NOTE" Original transaction refund_status: "FULLY_REFUNDED" The original sale is fully offset for compliance purposes. The two fields are derived differently: type is decided per credit note, by comparing that note's taxable_amount against the sale's. refund_status is cumulative, comparing every committed credit note's total against the sale's total_amount. On a single full refund they agree; across several partial refunds they can differ, so read refund_status when you need the sale's overall position. Partial Refunds When the credit note covers less than the original amount, Kintsugi records: Credit note type: "PARTIAL_CREDIT_NOTE" Original transaction refund_status: "PARTIALLY_REFUNDED" The sale is reduced, not erased. You can add further partial credit notes against the same transaction until the credited total reaches the original amount. Two caps apply, both against the remaining balance: Kintsugi checks the credit note total against what is still creditable on the sale, and separately checks each line against what is still creditable on the matching original line. Either one over is a 400 and nothing is written, so an over-refund is rejected rather than trimmed to fit. The transaction-level cap is the sale's total_amount plus any total_tax_amount_imported, minus everything already credited by committed credit notes. A PENDING credit note does not consume the balance, so two pending notes can each pass validation and then fail when you commit the second. ## Matching the Original Transaction Credit note line items should mirror the sale they reverse: Use the same external_product_id values Keep credited quantities at or below the original quantities Keep credited amounts at or below the original amounts That discipline gives you clean reporting on which products were returned, and an audit trail that holds up under review. Where an amount has to be spread across lines rather than itemized, Kintsugi allocates it in proportion to each line's remaining creditable balance, skipping lines that are already fully credited and giving the last eligible line the rounding remainder. Tax and quantity follow the same split, so a partial refund's tax reconciles against the lines it credited. ## Credit Note Statuses Credit notes use the same status values as transactions: PENDING: Created, refund not yet finalized COMMITTED: Refund complete and included in compliance calculations CANCELLED: Credit note voided, for example a reversed refund Move credit notes to COMMITTED once the refund has actually been processed so your compliance figures track reality. ## Updating Credit Notes Update with PUT /v1/transactions/{original_transaction_id}/credit_notes/{credit_note_id}. Typical cases: Status changes: Moving PENDING to COMMITTED after the refund settles Amount corrections: Fixing an incorrect refund figure Item adjustments: Revising which lines were credited Filed records lock: Once the original transaction is included in a filing, its credit notes are locked and can no longer be updated. Make corrections before the filing period closes. ## Best Practices Creating Credit Notes Mirror the original: Same products, same address treatment, amounts that reconcile Validate before you post: Check the remaining creditable balance so the request is not rejected Use descriptive external IDs: Tie the credit note back to the sale, for example CN-\{original_id\} Always send a description: The refund reason is the first thing anyone asks about months later Set status to match reality: PENDING while the refund is in flight, COMMITTED once it clears Finding Original Transactions Store Kintsugi transaction IDs: The credit note path parameter needs the Kintsugi ID, so save it when you create the transaction Fall back to external lookup: Without the Kintsugi ID, resolve it with GET /v1/transactions/external/{external_id} Handle not-found cleanly: The original transaction must exist before a credit note can reference it Error Handling Common failures when creating credit notes: Original transaction not found: Confirm you are passing the Kintsugi transaction ID, not your external_id Amount exceeds creditable balance: Subtract already-committed credit notes from the sale total plus imported tax before you post, and check the line-level balances too Sale cannot be credited: The sale must be PENDING, COMMITTED, or PARTIALLY_REFUNDED; cancelled and fully refunded sales are rejected Product mismatch: Reference the same products as the original line items Missing required fields: currency and status are required alongside external_id, date, total_amount, and transaction_items See the Error Handling guide for detailed strategies. ## Refund Scenarios Single Item Return A customer returns one item from a multi-item order: Find the original transaction Create a credit note containing only the returned line item Credit that item's share of the order Kintsugi marks the original transaction PARTIALLY_REFUNDED Full Order Refund The entire order is refunded: Find the original transaction Create a credit note containing every line item Credit the full original amount Kintsugi marks the original transaction FULLY_REFUNDED Multiple Partial Refunds Refunds arrive over time: Create a credit note for the first refund Add further credit notes as later refunds are issued Kintsugi tracks the cumulative credited total The original stays PARTIALLY_REFUNDED until the credited total reaches the original amount ## Refund Status Tracking Credit notes are cumulative. Each one reduces the remaining balance, and the refund status follows the total. Worked example Bar shows the amount still refundable Original transaction $100.00 Committed, nothing credited yet $100.00 remaining CREDIT NOTE 1 Partial refund −$30.00 PARTIALLY_REFUNDED $70.00 remaining CREDIT NOTE 2 Refunds the rest −$70.00 FULLY_REFUNDED $0.00 remaining Two credit notes of $70.00 against a $100.00 sale is rejected, not clamped: the second comes back 400 and nothing is written. Check the remaining balance before every credit note, not just the first. Refund Status on the Original Kintsugi derives refund_status on the sale from the credit notes committed against it. Until one is committed the field is absent rather than carrying a "not refunded" value, and only committed credit notes count: a PENDING credit note neither consumes the balance nor moves the status. PARTIALLY_REFUNDED Committed credit notes total less than the sale. The uncredited remainder still counts toward nexus, and the sale can carry further credit notes. FULLY_REFUNDED Committed credit notes reach the sale total. The sale nets to zero, the record stays for audit, and further credit notes are rejected. You can also set it directly: refund_status is writable on POST /v1/transactions and on update, which is how a historical import lands a sale that was already refunded before you integrated. Kintsugi recomputes it from committed credit notes whenever one is attached. See Transaction Statuses. ## Next Steps With refund handling in place: Verify credit notes: Read them back with GET /v1/transactions/{transaction_id} and filter the transaction list by transaction_type to review credit notes on their own. See the Get Transactions API reference. Monitor refund status: Track refund_status across your transactions so compliance figures stay accurate. Plan for edge cases: Decide up front how you handle reversed refunds and refunds that span filing periods. For endpoint-level detail, see: Create Credit Note Update Credit Note Get Transaction by ID --- # 5. Sales Tax Calculations Calculate accurate sales tax rates using Kintsugi's tax estimate endpoint in your checkout and billing flows Source: https://docs.trykintsugi.com/docs/api-guides/sales-tax-calculations The tax estimate endpoint ( POST /v1/tax/estimate) prices sales tax before you take payment. It is the core of the Level 2 (L2) tax engine, enabled once transaction sync (L1) is in place. Rates reflect your nexus, your product taxability, your customer's exemptions, and the address you are shipping to. This guide covers when to call it, how to shape the request, and how to use what comes back. ## Understanding Tax Estimates A tax estimate is a real-time calculation with no permanent transaction record behind it. Each estimate: Prices tax against your current registrations Applies the taxability rules for each product Honors customer exemptions Resolves rates for the destination jurisdiction Returns a per-line-item tax breakdown Because estimates create no transaction record, you can call the endpoint as often as customers change their cart or their address. Estimates do not sync transactions: /v1/tax/estimate calculates tax; it does not record a sale. For full compliance (L2), sync the transaction separately through /v1/transactions once payment is confirmed. Kintsugi determines nexus from those synced transactions, which is what makes accurate calculation possible in the first place, even when Kintsugi is not handling your filing and remittance. ## When to Calculate Tax Calculate during checkout or billing, after address entry and before payment processing. Common integration points: Shopping cart pages: When customers review their order Checkout flows: Once the shipping address is entered Subscription billing: When pricing a recurring charge Quote generation: When quoting a total to a customer Validate the address first: Run addresses through the address validation API before calculating. A verified address means a correct jurisdiction, and a correct jurisdiction means a correct rate. ## Tax Estimate Request Structure An estimate request mirrors the shape of a transaction sync request. Required Fields external_id: Your unique identifier for the transaction being priced date: Transaction date in ISO 8601 format currency: ISO 4217 currency code, for example USD addresses: At least one address, where SHIP_TO sets the jurisdiction transaction_items: The line items to price Optional Fields customer: The buyer. Send external_id to match a customer on file and pick up their exemptions description: A label for the estimate source: Where the transaction originated marketplace: Whether the sale runs through a marketplace. Defaults to false Transaction Items Each line item requires: date: Item date, normally matching the transaction date amount: Total amount for the line, after discounts And should carry: external_product_id: The product to price. Required unless you classify the item inline external_id: Your identifier for the line item quantity: Defaults to 1.0 exempt: Whether this specific line is exempt. Defaults to false Classifying an item inline: If external_product_id is missing or does not match a product on file, send both product_category and product_subcategory so Kintsugi can classify the item, optionally with product_name and product_description. Without either a known product or a category pair, the request fails. Pre-built catalogs keep classification consistent, so treat inline classification as a fallback rather than the default path. Addresses Every address entry needs a type of SHIP_TO or BILL_TO, plus street_1, street_2, city, county, state, postal_code, and country (ISO 3166-1 alpha-2). The SHIP_TO address decides which rates apply. When no SHIP_TO address is present, Kintsugi falls back to BILL_TO. ## Tax Estimate Response The response echoes your request and adds the calculation. At the top level: total_tax_amount_calculated: Total tax for the transaction taxable_amount: Total amount subject to tax tax_rate_calculated: Combined effective rate applied has_active_registration: Whether you hold an active registration for this transaction On each entry in transaction_items: tax_amount: Tax for that line taxable_amount: The portion of the line subject to tax tax_rate: Combined rate applied to the line exempt and exempt_reason: Whether the line was exempt, and why tax_items: The rate components that make up the line's tax, each with a name, rate, amount, and exempt flag Amounts come back as strings: Monetary values and rates are returned as decimal strings, for example "20.00" and "0.08". Parse them with a decimal-safe type rather than a float so cents do not drift, and note that nexus_met is deprecated in favor of has_active_registration. Using Tax Amounts Take the figures from the response to: Show tax to customers during checkout Calculate the final total Carry tax amounts into the transaction you sync later Sanity-check the calculation before you charge Keep the estimate: Store the response so the transaction you sync afterward carries the same tax amounts the customer saw. Your records and your receipts then agree. ## Tax Calculation Workflow The Three Calls Each one gates the next. A bad address gives a wrong rate; an unrecorded sale never reaches your filings. CALL 1 Validate the address Destination decides the rate, down to the local jurisdiction. Recommended rather than required, but it is what fills in the county. / v1/ address_validation/ search CALL 2 Quote the tax Returns amounts and the jurisdictions they belong to. Nothing is recorded. / v1/ tax/ estimate CALL 3 Record the sale Only after payment succeeds, carrying the tax you quoted. / v1/ transactions Checkout Sequence Solid step numbers are the Kintsugi calls. Everything else happens in your storefront. 1 Cart assembled, address entered Your storefront. No Kintsugi call yet. 2 Validate the address POST /v1/address_validation/search Recommended Use the returned response_address from here on. It is the standardized version, and enrich_fields tells you what it added: county is the usual one, and local rates depend on it. verification_status tells you how far it got. 3 Assemble the estimate request date external_id currency addresses transaction_items Line items carry the tax category, so each one needs an existing product record or an inline product_category and product_subcategory pair. 4 Calculate tax POST /v1/tax/estimate Returns a quote RETURNS Tax amounts broken out by the jurisdictions that levy them, on each line item's tax_items. A quote only: nothing is stored, and there is no estimate id or expiry to track. 5 Show the total with tax Display the quoted amount before the customer pays, not after. 6 Process payment DECLINED → Send the customer back to the cart. The estimate was never recorded, so there is nothing to reverse in Kintsugi. 7 Sync the transaction with the tax amounts ## Tax Calculation Workflow POST /v1/transactions status: COMMITTED Send the tax you actually charged on total_tax_amount_imported, and per line on tax_amount_imported. That is the collected figure; Kintsugi weighs it against its own calculation to set your liability, so a recalculation here can silently disagree with the customer's receipt. See transaction statuses for what COMMITTED does. 8 Order complete The sale counts toward nexus and appears in filings. An estimate is not a record. If step 7 never runs, the sale is invisible to nexus and filings even though the customer was charged tax. ## Nexus and Tax Calculation Kintsugi calculates tax where you hold an active registration. The has_active_registration flag on the response tells you which side of that line the transaction fell. When Tax Is Calculated Tax applies when: You hold an active registration in the customer's jurisdiction The product is taxable there No valid exemption covers the sale When Tax Is Zero Tax is zero when: You hold no active registration in that jurisdiction The product is exempt there A valid customer or line-level exemption applies In the exempt cases, exempt_reason on the line item tells you which rule zeroed it out, whether that was the product, the customer, the region, or something else. Estimates reflect the present: Each estimate uses your registration and nexus status at the moment of the request. Register in a new jurisdiction and subsequent estimates will price tax there, without any change on your side. ## Customer Exemptions To have an exempt customer's status applied, reference the customer on the estimate: { "date": "2026-01-15T10:00:00Z", "external_id": "EST-2026-001", "currency": "USD", "customer": { "external_id": "CUST-789", "name": "Northwind Nonprofit" }, "transaction_items": [ { "external_id": "ITEM-001", "date": "2026-01-15T10:00:00Z", "external_product_id": "PROD-12345", "quantity": 1, "amount": 100.00 } ], "addresses": [ { "type": "SHIP_TO", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } ] } When the external_id matches a customer on file, Kintsugi applies that customer's exemptions. If the customer is not found, the details are ignored for exemption purposes and the estimate still returns. For one-off exemptions that are not tied to a customer record, set exempt: true on the relevant line items instead. See the Product & Customer Records guide for how to create exempt customers. ## Error Handling Common failures when calculating tax: Product cannot be classified: Send a known external_product_id, or both product_category and product_subcategory Invalid address: Validate addresses before calculating Missing required fields: date, external_id, currency, addresses, and transaction_items are all required Missing authentication headers: Every request needs both x-api-key and x-organization-id Rate limiting: Retry with exponential backoff See the Error Handling guide for detailed strategies. ## Best Practices Request Structure Use consistent external IDs: Keep one identifier across the estimate and the transaction that follows it Validate addresses first: Verified addresses resolve to the right jurisdiction Reference products precisely: external_product_id values must match your product records Send complete line items: Every item needs a date and an amount Response Handling Store the response: Carry the same tax amounts into transaction sync Handle zero tax: No registration and valid exemptions are normal outcomes, not errors Show the breakdown: Surface tax_items so customers and your support team can see how tax was composed Parse decimals safely: Amounts and rates arrive as strings Performance Cache short-lived estimates: Reuse a result while the cart and address are unchanged Debounce address input: Wait for typing to settle before calling Fail gracefully: Decide in advance what checkout shows if an estimate fails Watch your call volume: Track usage so you see rate pressure before your customers do ## Integration Patterns E-Commerce Checkout Customer adds items to the cart Customer enters a shipping address Validate the address Calculate tax with /v1/tax/estimate Display the total with tax Process payment Sync the transaction with those tax amounts Subscription Billing Customer selects a plan Customer provides a billing address Calculate tax for the first billing cycle Store the tax amount for recurring charges Recalculate when the address changes or the subscription renews Multi-Step Checkout Calculate tax once the shipping address step is complete Recalculate when the customer changes address Recalculate when the customer changes the cart Update the displayed total after each recalculation ## Reading the Tax Breakdown Each line item's tax_items array shows the rate components behind its tax, for example a state rate and a county rate, each with its own name, rate, and amount. Together with the line's tax_rate and tax_amount, and the transaction-level total_tax_amount_calculated, that gives you a complete picture of the calculation. Use it to: Show customers how their tax was composed Produce receipts and invoices with real tax detail Debug unexpected results against a specific rate component Reconcile totals before you charge ## Next Steps With tax calculation integrated: Sync transactions: After payment, sync the sale with the tax amounts from the estimate. See the Syncing Transaction Records guide. Handle errors: Build the failure path before you need it. See the Error Handling guide. Tune performance: Cache and debounce to cut calls and keep checkout fast. For endpoint-level detail, see: Estimate Tax Address Validation --- # Error Handling Learn how to handle API errors and implement robust error handling Source: https://docs.trykintsugi.com/docs/advanced/error-handling ## Error Response Format All Kintsugi API errors follow a consistent JSON format: { "detail": "Error message describing what went wrong" } For validation errors (422), the response includes detailed field-level information: { "detail": [ { "type": "missing", "loc": ["body", "external_id"], "msg": "Field required", "input": null } ] } ## HTTP Status Codes Client errors 4xx · 7 codes Fix the request, then retry. 400 Bad Request Invalid request data or parameters. Common causes Missing required fields Invalid data types Business logic violations 401 Unauthorized Invalid or missing authentication. Common causes Missing API key Invalid API key Expired token 403 Forbidden Insufficient permissions. Common causes No access to organization Admin-only endpoint 404 Not Found Resource does not exist. Common causes Invalid ID Deleted resource Wrong organization 409 Conflict Resource conflict. Common causes Duplicate creation State conflicts Concurrent modifications 422 Unprocessable Entity Validation errors. Common causes Invalid field values Constraint violations Business rules 429 Too Many Requests Rate limit exceeded. Common causes Over 10,000 requests per minute Server errors 5xx · 2 codes Retry with backoff. 500 Internal Server Error Unexpected server error. Common causes Database errors Unhandled exceptions System failures 503 Service Unavailable External service unavailable. Common causes Third-party API failures Maintenance windows ## Common Error Messages Authentication Errors Missing API Key Error Response { "detail": "API key is missing or empty." } Solution Include your API key in the x-api-key header (lowercase with hyphens): curl -H "x-api-key: your-api-key" \ -H "x-organization-id: your-org-id" \ https://api.trykintsugi.com/v1/tax/estimate Important: Kintsugi requires both x-api-key and x-organization-id headers for authentication. This is API key authentication via headers, not bearer token authentication. Invalid API Key Error Response { "detail": "Unauthenticated request." } Solution Verify your API key is correct Check if the API key is active Ensure you're using the organization API key, not a personal key Organization Access Denied Error Response { "detail": "User does not have access to the specified organization" } Solution Ensure your API key has access to the organization specified in the x-organization-id header: curl -H "x-api-key: your-api-key" \ -H "x-organization-id: your-org-id" \ https://api.trykintsugi.com/v1/tax/estimate Your Organization ID can be found in the lower left-hand corner of the Kintsugi Platform dashboard after logging in. Admin Access Required Error Response { "detail": "Admin access required for this endpoint." } Solution Use an admin-level API key for this operation. Admin endpoints require elevated permissions. Validation Errors Missing Required Fields { "detail": [ { "type": "missing", "loc": ["body", "external_id"], "msg": "Field required", "input": null } ] } Solution: Include all required fields in your request Invalid Field Values { "detail": [ { "type": "enum", "loc": ["body", "currency"], "msg": "Input should be 'USD', 'CAD', 'EUR'...", "input": "INVALID", "ctx": {"expected": "one of USD, CAD, EUR..."} } ] } ## Common Error Messages Solution: Use valid enum values as specified in the API documentation Business Logic Violations { "detail": [ { "type": "value_error", "loc": ["body", "discount_amount"], "msg": "'discount_amount' must be less than the 'amount'.", "input": 100.00, "ctx": {"error": "discount exceeds amount"} } ] } Solution: Ensure your data follows business rules and constraints ## Error Handling Best Practices Implement Proper HTTP Status Code Handling Check the response status code and handle each type appropriately: import requests try: response = requests.get(url, headers=headers) response.raise_for_status() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: \# Handle authentication error print("Invalid API key") elif e.response.status_code == 429: \# Handle rate limiting retry_after = e.response.headers.get('Retry-After', 60) print(f"Rate limited. Retry after {retry_after} seconds") elif e.response.status_code == 422: \# Handle validation errors errors = e.response.json()['detail'] for error in errors: print(f"Validation error: {error['msg']}") Implement Exponential Backoff For rate limiting and temporary errors, implement exponential backoff: import time import random def make_request_with_retry(url, headers, max_retries=3): for attempt in range(max_retries): try: response = requests.get(url, headers=headers) response.raise_for_status() return response except requests.exceptions.HTTPError as e: if e.response.status_code == 429: \# Exponential backoff with jitter wait_time = (2 ** attempt) + random.uniform(0, 1) time.sleep(wait_time) continue else: raise raise Exception("Max retries exceeded") Log Errors Appropriately Log errors with sufficient context for debugging: import logging logger = logging.getLogger(__name__) try: response = requests.get(url, headers=headers) response.raise_for_status() except requests.exceptions.HTTPError as e: logger.error( "API request failed", extra={ "status_code": e.response.status_code, "url": url, "response_body": e.response.text, "organization_id": headers.get("x-organization-id") } ) raise Provide User-Friendly Error Messages Transform technical errors into user-friendly messages: ## Error Handling Best Practices def handle_api_error(error): if error.response.status_code == 401: return "Please check your API key and try again." elif error.response.status_code == 404: return "The requested resource was not found." elif error.response.status_code == 422: return "Please check your input data and try again." elif error.response.status_code == 429: return "Too many requests. Please wait a moment and try again." else: return "An unexpected error occurred. Please try again later." ## Troubleshooting Common Issues Authentication Issues Missing API Key Error: API key is missing or empty. Solution: Ensure you're including both the x-api-key and x-organization-id headers in your requests: curl -H "x-api-key: your-api-key" \ -H "x-organization-id: your-org-id" \ https://api.trykintsugi.com/v1/tax/estimate Kintsugi uses API key authentication via headers (not bearer token). Both headers are required. Invalid API Key Error: Unauthenticated request. Solution: Verify your API key is correct Check if the API key is active Ensure you're using the organization API key, not a personal key Validation Issues Missing Required Fields Error: Field required Solution: Check the API documentation for required fields and ensure all are included in your request body. Invalid Data Types Error: Input should be 'USD', 'CAD', 'EUR'... Solution: Use the correct data types and enum values as specified in the API documentation. Resource Issues Resource Not Found Error: Resource not found Solution: Verify the resource ID is correct Check if the resource belongs to your organization Ensure the resource hasn't been deleted Access Denied Error: User does not have access to the specified organization Solution: Ensure your API key has access to the organization specified in the x-organization-id header. Your Organization ID can be found in the lower left-hand corner of the Kintsugi Platform dashboard after logging in. ## Related Resources Getting Started API Reference Support --- # SDK Overview The official Kintsugi SDKs, and what each one covers Source: https://docs.trykintsugi.com/docs/sdks/overview Five official SDKs. Python, TypeScript, Java, PHP and Ruby, each published to its language's package registry and generated from the same OpenAPI spec that produces this API reference. Generating the SDKs from the spec keeps them in step with the API. Request and response types, enums and error shapes all come from it, so a new field reaches the SDK the same day it reaches the API, and no hand written client drifts out of date behind you. ## Supported languages Python pip install kintsugi-tax-platform-sdk TypeScript npm add @kintsugi-tax/tax-platform-sdk Java com.trykintsugi:kintsugi-tax-java-sdk PHP composer require kintsugi-tax/tax-platform-sdk Ruby gem install kintsugi_sdk ## Packages | Language | Package | Registry | Requires | | ---------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------- | --------- | | Python | kintsugi-tax-platform-sdk | PyPI | 3.10+ | | TypeScript | @kintsugi-tax/tax-platform-sdk | npm | see RUNTIMES.md | | Java | com.trykintsugi:kintsugi-tax-java-sdk | Maven Central | JDK 11+ | | PHP | kintsugi-tax/tax-platform-sdk | Packagist | PHP 8.2+ | | Ruby | kintsugi_sdk | RubyGems | Ruby 3.2+ | ## What you get Typed requests and responses Generated models for every request body, enum and response. Your editor completes the field names, and your compiler or type checker catches the mistakes before a request ever leaves your process. Credentials in one place Set your API key once when you construct the client, and it authenticates every call that accepts it. A handful of operations take credentials per call, and the code sample on each reference page shows which. Typed errors Every operation declares the errors it can return, so a validation failure arrives as a distinct type instead of a status code you parse by hand. See Error handling. Retries (Python and TypeScript) Configurable backoff for transient failures, per call or for the whole client. Async (Python) Every method has an _async variant, so calls can run concurrently without tying up a thread. ## Coverage Python, TypeScript, Java and PHP cover every endpoint in the API reference. Ruby covers part of it today: customers, transactions, exemptions, address validation, tax estimation, and some of nexus and products. The Partner API is a separate surface. An SDK reaches a partner endpoint only where that same endpoint also appears in the API reference, which covers customers, transactions, exemptions, filings, registrations, nexus, products, address validation and tax estimation. Everything the Partner API adds beyond that sits outside the SDKs: all of the partner specific /v2 endpoints, along with its additional /v1 endpoints for organizations, users, API keys, connections, bank details, product configs, filing generation and reports. Call those over HTTP. You are never left guessing which is which. Every reference page carries a code sample in all five languages. Where an SDK covers the endpoint, the sample is that SDK's call, with its install line beside it. Where it does not, the sample is the same request written against the language's standard HTTP client, and the pane says so. ## Getting started Get an API key Create one in the Kintsugi app. See Creating and managing API keys. Install the SDK Take the package for your language from the table above. Make your first call Work through the Quick start, then the guide for your language. Prefer plain HTTP? Every reference page has a cURL sample too, and Making an authenticated request walks through the raw request end to end. --- # SDK Quick Start Install a Kintsugi SDK and make your first authenticated call Source: https://docs.trykintsugi.com/docs/sdks/quick-start This page gets your first call working. For the detail behind it, including async, retries and error types, see the Python, TypeScript, Java, PHP and Ruby guides. ## Prerequisites A Kintsugi account An API key, created in the app (see Creating and managing API keys) Keep your API key out of version control and out of browser bundles. Read it from an environment variable, and call the API from your server. ## Install and call Install the SDK for your language, then fetch a customer by id. That is the whole loop: authenticate once, call a method, read a typed response. Python pip install kintsugi-tax-platform-sdk import os from kintsugi_tax_platform_sdk import SDK, models with SDK( security=models.Security( api_key_header=os.environ["KINTSUGI_API_KEY"], ), ) as sdk: res = sdk.customers.get(customer_id="cust_abc123") \# Handle response print(res) TypeScript npm add @kintsugi-tax/tax-platform-sdk import { SDK } from "@kintsugi-tax/tax-platform-sdk"; const sdk = new SDK({ security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "", }, }); async function run() { const result = await sdk.customers.get({ customerId: "cust_abc123", }); console.log(result); } run(); Java implementation 'com.trykintsugi:kintsugi-tax-java-sdk:0.15.3' package hello.world; import com.kintsugi.taxplatform.SDK; import com.kintsugi.taxplatform.models.components.Security; import com.kintsugi.taxplatform.models.operations.GetCustomerByIdV1CustomersCustomerIdGetResponse; public class Application { public static void main(String[] args) throws Exception { SDK sdk = SDK.builder() .security(Security.builder() .apiKeyHeader(System.getenv().getOrDefault("KINTSUGI_API_KEY", "")) .build()) .build(); GetCustomerByIdV1CustomersCustomerIdGetResponse res = sdk.customers().getById() .customerId("cust_abc123") .call(); if (res.customerRead().isPresent()) { System.out.println(res.customerRead().get()); } } } PHP composer require "kintsugi-tax/tax-platform-sdk" declare(strict_types=1); require 'vendor/autoload.php'; use KintsugiTax\SDK; use KintsugiTax\SDK\Models\Components; $sdk = SDK\SDK::builder() ->setSecurity( new Components\Security( apiKeyHeader: getenv('KINTSUGI_API_KEY'), ) ) ->build(); ## Install and call $response = $sdk->customers->getById( customerId: 'cust_abc123' ); if ($response->customerRead !== null) { // handle response } Ruby gem install kintsugi_sdk require 'kintsugi_sdk' Models = ::KintsugiSDK::Models s = ::KintsugiSDK::OpenApiSDK.new( security: Models::Shared::Security.new( api_key_header: ENV.fetch('KINTSUGI_API_KEY') ) ) req = Models::Ops::GetCustomerByIdV1CustomersCustomerIdGetRequest.new( customer_id: 'cust_abc123' ) res = s.customers.get(request: req) unless res.nil? \# handle response end ## Estimate tax Tax estimation is where most integrations begin. Send the line items and addresses, get back the tax owed, and nothing is recorded against the organization: Python import os from kintsugi_tax_platform_sdk import SDK, models from kintsugi_tax_platform_sdk.utils import parse_datetime with SDK( security=models.Security(api_key_header=os.environ["KINTSUGI_API_KEY"]), ) as sdk: res = sdk.tax_estimation.estimate( date_=parse_datetime("2025-01-23T13:01:29.949Z"), external_id="txn_12345", currency=models.CurrencyEnum.USD, transaction_items=[ { "external_id": "item_A", "date_": parse_datetime("2025-01-23T13:01:29.949Z"), "external_product_id": "prod_abc", "quantity": 2, "amount": 100, }, ], addresses=[ { "type": models.TransactionEstimatePublicRequestType.SHIP_TO, "street_1": "789 Pine St", "city": "Austin", "state": "TX", "postal_code": "78701", "country": "US", }, ], marketplace=False, ) print(res) TypeScript import { SDK } from "@kintsugi-tax/tax-platform-sdk"; const sdk = new SDK({ security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "" }, }); const result = await sdk.taxEstimation.estimate({ transactionEstimatePublicRequest: { date: new Date("2025-01-23T13:01:29.949Z"), externalId: "txn_12345", currency: "USD", transactionItems: [ { externalId: "item_A", date: new Date("2025-01-23T13:01:29.949Z"), externalProductId: "prod_abc", quantity: 2, amount: 100, }, ], addresses: [ { type: "SHIP_TO", street1: "789 Pine St", city: "Austin", state: "TX", postalCode: "78701", country: "US", }, ], }, }); console.log(result); Java package hello.world; ## Estimate tax import com.kintsugi.taxplatform.SDK; import com.kintsugi.taxplatform.models.components.*; import com.kintsugi.taxplatform.models.operations.EstimateTaxV1TaxEstimatePostResponse; import java.time.OffsetDateTime; import java.util.List; public class Application { public static void main(String[] args) throws Exception { SDK sdk = SDK.builder() .security(Security.builder() .apiKeyHeader(System.getenv().getOrDefault("KINTSUGI_API_KEY", "")) .build()) .build(); EstimateTaxV1TaxEstimatePostResponse res = sdk.taxEstimation().estimate() .transactionEstimatePublicRequest(TransactionEstimatePublicRequest.builder() .date(OffsetDateTime.parse("2025-01-23T13:01:29.949Z")) .externalId("txn_12345") .currency(CurrencyEnum.USD) .transactionItems(List.of( TransactionItemEstimateBase.builder() .date(OffsetDateTime.parse("2025-01-23T13:01:29.949Z")) .amount(100d) .externalId("item_A") .externalProductId("prod_abc") .quantity(2d) .build())) .addresses(List.of( TransactionEstimatePublicRequestAddress.builder() .type(TransactionEstimatePublicRequestType.SHIP_TO) .street1("789 Pine St") .city("Austin") .state("TX") .postalCode("78701") .country("US") .build())) .build()) .call(); if (res.pageTransactionEstimateResponse().isPresent()) { System.out.println(res.pageTransactionEstimateResponse().get()); } } } PHP declare(strict_types=1); require 'vendor/autoload.php'; use KintsugiTax\SDK; use KintsugiTax\SDK\Models\Components; use KintsugiTax\SDK\Utils; $sdk = SDK\SDK::builder() ->setSecurity( new Components\Security( apiKeyHeader: getenv('KINTSUGI_API_KEY'), ) ) ->build(); ## Estimate tax $transactionEstimatePublicRequest = new Components\TransactionEstimatePublicRequest( date: Utils\Utils::parseDateTime('2025-01-23T13:01:29.949Z'), externalId: 'txn_12345', currency: Components\CurrencyEnum::Usd, transactionItems: [ new Components\TransactionItemEstimateBase( externalId: 'item_A', date: Utils\Utils::parseDateTime('2025-01-23T13:01:29.949Z'), externalProductId: 'prod_abc', quantity: 2, amount: 100, ), ], addresses: [ new Components\TransactionEstimatePublicRequestAddress( type: Components\TransactionEstimatePublicRequestType::ShipTo, street1: '789 Pine St', city: 'Austin', state: 'TX', postalCode: '78701', country: 'US', ), ], ); $response = $sdk->taxEstimation->estimate( transactionEstimatePublicRequest: $transactionEstimatePublicRequest ); if ($response->pageTransactionEstimateResponse !== null) { // handle response } Ruby require 'kintsugi_sdk' Models = ::KintsugiSDK::Models s = ::KintsugiSDK::OpenApiSDK.new( security: Models::Shared::Security.new( api_key_header: ENV.fetch('KINTSUGI_API_KEY') ) ) req = Models::Ops::EstimateTaxV1TaxEstimatePostRequest.new( transaction_estimate_public_request: Models::Shared::TransactionEstimatePublicRequest.new( date: DateTime.iso8601('2025-01-23T13:01:29.949Z'), external_id: 'txn_12345', currency: Models::Shared::CurrencyEnum::USD, transaction_items: [ Models::Shared::TransactionItemEstimateBase.new( external_id: 'item_A', date: DateTime.iso8601('2025-01-23T13:01:29.949Z'), external_product_id: 'prod_abc', quantity: 2.0, amount: 100.0 ), ], addresses: [ Models::Shared::Addresses.new( type: Models::Shared::Type::SHIP_TO, street_1: '789 Pine St', city: 'Austin', state: 'TX', postal_code: '78701', country: 'US' ), ] ) ) res = s.tax_estimation.estimate_tax(request: req) unless res.nil? \# handle response end ## Estimate tax The Estimate tax reference page lists every field, with a sample in each language. ## Next steps API reference Every endpoint, with a sample per language Error handling What the API returns, and when to retry Calculate tax A worked end-to-end recipe Integration guide How the pieces fit together --- # Python SDK Install, authenticate and call the Kintsugi API from Python Source: https://docs.trykintsugi.com/docs/sdks/python Official Python SDK. kintsugi-tax-platform-sdk is published on PyPI and generated from the same OpenAPI spec that produces this API reference, so it stays in step with the API. Python 3.10 or later. Every method carries full type hints and comes in both a synchronous and an asynchronous form, so the SDK fits a script and a high throughput service equally well. ## Installation pip install kintsugi-tax-platform-sdk uv add kintsugi-tax-platform-sdk poetry add kintsugi-tax-platform-sdk ## Authentication The API authenticates with an API key header. Create a key in the Kintsugi app (see Creating and managing API keys), pass it once when you build the client, and every call that accepts it is authenticated: from kintsugi_tax_platform_sdk import SDK, models with SDK( security=models.Security( api_key_header="", ), ) as sdk: res = sdk.customers.get(customer_id="cust_abc123") \# Handle response print(res) The client is a context manager, so with releases the underlying HTTP connection when the block ends. Keeping a long lived client is also fine: call sdk.close() when you are finished with it. A handful of operations take credentials per call rather than per client. The code sample on each API reference page shows a security= argument where that applies, using an operation specific type such as models.SearchV1AddressValidationSearchPostSecurity. ## Making a request Request bodies are keyword arguments, and every enum has a generated type, so misspelled fields and invalid values fail in your editor rather than in production: from kintsugi_tax_platform_sdk import SDK, models with SDK( security=models.Security(api_key_header=""), ) as sdk: res = sdk.customers.create( name="Jane Smith", email="jane.smith@example.com", external_id="cust_002", street_1="456 Elm St", city="Metropolis", state="NY", postal_code="10001", country=models.CountryCodeEnum.US, status=models.StatusEnum.ACTIVE, ) print(res) For the exact call on any endpoint, including arguments, enums and the type it returns, open that endpoint in the API reference and select the Python tab. ## Async Every method has an _async counterpart, so calls can run concurrently without tying up a thread: import asyncio from kintsugi_tax_platform_sdk import SDK, models async def main(): async with SDK( security=models.Security(api_key_header=""), ) as sdk: res = await sdk.customers.get_async(customer_id="cust_abc123") print(res) asyncio.run(main()) ## Error handling errors.SDKError is the base class for HTTP error responses. It carries message, status_code, headers, body and raw_response, and some errors also carry parsed data: from kintsugi_tax_platform_sdk import SDK, errors, models with SDK( security=models.Security(api_key_header=""), ) as sdk: try: res = sdk.customers.get(customer_id="cust_abc123") print(res) except errors.SDKError as e: print(e.status_code) print(e.message) print(e.body) if isinstance(e, errors.ErrorResponse): print(e.data.detail) Operations declare their own error types for validation failures, such as errors.BackendSrcCustomersResponsesValidationErrorResponse for a 422. Each method's error table is in the SDK's docs, and network failures surface as the underlying httpx exceptions. Error handling covers what the API returns and when a retry is worthwhile. ## Retries Transient failures are retried with backoff. Configure it per call, or once for the whole client: from kintsugi_tax_platform_sdk import SDK, models from kintsugi_tax_platform_sdk.utils import BackoffStrategy, RetryConfig with SDK( security=models.Security(api_key_header=""), retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False), ) as sdk: res = sdk.customers.list(page=1, size=50) print(res) ## Overriding the server URL from kintsugi_tax_platform_sdk import SDK, models with SDK( server_url="https://api.trykintsugi.com", security=models.Security(api_key_header=""), ) as sdk: ... ## Available resources AddressValidation search, suggestions Customers list, create, get, update, get_by_external_id, get_transactions, create_transaction Exemptions list, create, get, upload_certificate, list_attachments Filings get_all, get, get_by_registration_id Nexus get_physical, create_physical, update_physical_nexus, delete_physical_nexus, get_all Products get_products_v1_products_get, create_product_v1_products_post, get_product_categories_v1_products_categories_get, retrieve, update Registrations get_all, create, get, update, deregister TaxEstimation estimate Transactions list, create, get_by_external_id, update, get_by_id, get_by_filing_id, create_credit_note, update_credit_note Python SDK repository Source, per-method docs, releases and issues API reference Every endpoint, with a Python sample on each page --- # TypeScript SDK Install, authenticate and call the Kintsugi API from TypeScript or JavaScript Source: https://docs.trykintsugi.com/docs/sdks/typescript Official TypeScript SDK. @kintsugi-tax/tax-platform-sdk is published on npm and generated from the same OpenAPI spec that produces this API reference, so it stays in step with the API. The package ships CommonJS and ES module builds with full type definitions, and every operation is also available as a standalone, tree shakeable function. RUNTIMES.md lists the supported JavaScript runtimes. ## Installation npm add @kintsugi-tax/tax-platform-sdk pnpm add @kintsugi-tax/tax-platform-sdk yarn add @kintsugi-tax/tax-platform-sdk bun add @kintsugi-tax/tax-platform-sdk ## Authentication The API authenticates with an API key header. Create a key in the Kintsugi app (see Creating and managing API keys), pass it once when you construct the client, and every call that accepts it is authenticated: import { SDK } from "@kintsugi-tax/tax-platform-sdk"; const sdk = new SDK({ security: { apiKeyHeader: "", }, }); async function run() { const result = await sdk.customers.get({ customerId: "cust_abc123", }); console.log(result); } run(); Never ship an API key to a browser. Call the API from your server, or from a route handler that keeps the key server side. A handful of operations take credentials per call rather than per client. The code sample on each API reference page shows those methods taking the security object as their first argument. ## Making a request Arguments are camelCased and request bodies are plain objects, fully typed, so your editor completes each field and the compiler catches the rest: import { SDK } from "@kintsugi-tax/tax-platform-sdk"; const sdk = new SDK({ security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "" }, }); const result = await sdk.customers.create({ name: "Jane Smith", email: "jane.smith@example.com", externalId: "cust_002", street1: "456 Elm St", city: "Metropolis", state: "NY", postalCode: "10001", country: "US", status: "ACTIVE", }); console.log(result); For the exact call on any endpoint, including arguments, enums and the type it returns, open that endpoint in the API reference and select the TypeScript tab. ## Tree-shaking with standalone functions Each method is also exported as a standalone function taking an SDKCore, so a bundle ships only the operations it actually calls: import { SDKCore } from "@kintsugi-tax/tax-platform-sdk/core.js"; import { customersList } from "@kintsugi-tax/tax-platform-sdk/funcs/customersList.js"; const sdk = new SDKCore({ security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "" }, }); const res = await customersList(sdk, { page: 1, size: 50 }); if (res.ok) { console.log(res.value); } else { console.error(res.error); } Standalone functions return a result object instead of throwing, which suits code that would rather branch than catch. ## Error handling SDKError is the base class for HTTP error responses. It carries message, statusCode, headers, body and rawResponse, and some errors also carry parsed data: import { SDK } from "@kintsugi-tax/tax-platform-sdk"; import * as errors from "@kintsugi-tax/tax-platform-sdk/models/errors"; const sdk = new SDK({ security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "" }, }); try { const result = await sdk.customers.get({ customerId: "cust_abc123" }); console.log(result); } catch (error) { if (error instanceof errors.SDKError) { console.error(error.statusCode, error.message, error.body); } throw error; } Operations declare their own error types for validation failures, such as errors.BackendSrcCustomersResponsesValidationErrorResponse for a 422. Each method's error table is in the SDK's docs. Error handling covers what the API returns and when a retry is worthwhile. ## Retries Transient failures are retried with backoff. Configure it per call, or once for the whole client: import { SDK } from "@kintsugi-tax/tax-platform-sdk"; const sdk = new SDK({ security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "" }, retryConfig: { strategy: "backoff", backoff: { initialInterval: 1, maxInterval: 50, exponent: 1.1, maxElapsedTime: 100, }, retryConnectionErrors: false, }, }); ## Overriding the server URL const sdk = new SDK({ serverURL: "https://api.trykintsugi.com", security: { apiKeyHeader: process.env.KINTSUGI_API_KEY ?? "" }, }); ## Available resources AddressValidation search, suggest Customers list, create, get, update, getByExternalId, getTransactions, createTransaction Exemptions list, create, get, uploadCertificate, getAttachments Filings list, get, getByRegistrationId Nexus listPhysical, createPhysical, updatePhysical, deletePhysical, list Products getProductsV1ProductsGet, createProductV1ProductsPost, getProductCategoriesV1ProductsCategoriesGet, get, update Registrations get, create, getById, update, deregister TaxEstimation estimate Transactions get, create, getByExternalId, update, getById, getByFilingId, createCreditNote, updateCreditNote TypeScript SDK repository Source, per-method docs, releases and issues API reference Every endpoint, with a TypeScript sample on each page --- # Java SDK Install, authenticate and call the Kintsugi API from Java Source: https://docs.trykintsugi.com/docs/sdks/java Official Java SDK. com.trykintsugi:kintsugi-tax-java-sdk is published on Maven Central and generated from the same OpenAPI spec that produces this API reference, so it stays in step with the API. JDK 11 or later. Requests and models are immutable builders and responses are typed objects, so an invalid request fails at compile time rather than in production. ## Installation implementation 'com.trykintsugi:kintsugi-tax-java-sdk:0.15.3' com.trykintsugi kintsugi-tax-java-sdk 0.15.3 Maven Central lists the current version. ## Authentication The API authenticates with an API key header. Create a key in the Kintsugi app (see Creating and managing API keys), pass it once to the builder, and every call that accepts it is authenticated: package hello.world; import com.kintsugi.taxplatform.SDK; import com.kintsugi.taxplatform.models.components.Security; import com.kintsugi.taxplatform.models.operations.GetCustomerByIdV1CustomersCustomerIdGetResponse; public class Application { public static void main(String[] args) throws Exception { SDK sdk = SDK.builder() .security(Security.builder() .apiKeyHeader(System.getenv().getOrDefault("KINTSUGI_API_KEY", "")) .build()) .build(); GetCustomerByIdV1CustomersCustomerIdGetResponse res = sdk.customers().getById() .customerId("cust_abc123") .call(); if (res.customerRead().isPresent()) { System.out.println(res.customerRead().get()); } } } Bodies come back as Optional, so an absent body is something the compiler makes you handle rather than a null waiting to happen. A handful of operations take credentials per call rather than per client. The code sample on each API reference page shows a .security(...) step where that applies, using an operation specific type such as SearchV1AddressValidationSearchPostSecurity. ## Making a request Request bodies are component builders, passed with .request(...). Required fields are enforced at build time and enums are generated types, so an invalid request will not compile: CustomerCreate req = CustomerCreate.builder() .name("Jane Smith") .email("jane.smith@example.com") .externalId("cust_002") .street1("456 Elm St") .city("Metropolis") .state("NY") .postalCode("10001") .country(CountryCodeEnum.US) .status(StatusEnum.ACTIVE) .build(); CreateCustomerV1CustomersPostResponse res = sdk.customers().create() .request(req) .call(); For the exact call on any endpoint, including its builder type, arguments and the type it returns, open that endpoint in the API reference and select the Java tab. ## Error handling Every SDK exception inherits from SDKError, which exposes message(), code(), headers, body(), bodyAsString() and rawResponse(). Catch it, then narrow to the operation's typed errors: try { GetCustomerByIdV1CustomersCustomerIdGetResponse res = sdk.customers().getById() .customerId("cust_abc123") .call(); res.customerRead().ifPresent(System.out::println); } catch (SDKError ex) { System.out.println(ex.code() + " " + ex.bodyAsString()); if (ex instanceof ErrorResponse) { ((ErrorResponse) ex).data() .ifPresent(payload -> System.out.println(payload.detail())); } } catch (UncheckedIOException ex) { // Connection failure, timeout, and other I/O errors } Each method's error table is in the SDK's docs. Error handling covers what the API returns and when a retry is worthwhile. ## Overriding the server URL SDK sdk = SDK.builder() .serverURL("https://api.trykintsugi.com") .security(Security.builder() .apiKeyHeader(System.getenv().getOrDefault("KINTSUGI_API_KEY", "")) .build()) .build(); ## Available resources AddressValidation search, suggest Customers get, create, getById, update, getByExternalId, createTransaction Customers.Transactions getByCustomerId Exemptions get, create, getById, uploadCertificate, getAttachments Filings get, getById, getByRegistrationId Nexus getPhysical, createPhysical, updatePhysical, deletePhysical, get Products getProductsV1ProductsGet, createProductV1ProductsPost, getProductCategoriesV1ProductsCategoriesGet, getById, update Registrations get, create, getById, update, deregister TaxEstimation estimate Transactions get, create, getByExternalId, update, getById, getByFilingId, updateCreditNote Transactions.CreditNotes create Java SDK repository Source, per-method docs, releases and issues API reference Every endpoint, with a Java sample on each page --- # PHP SDK Install, authenticate and call the Kintsugi API from PHP Source: https://docs.trykintsugi.com/docs/sdks/php Official PHP SDK. kintsugi-tax/tax-platform-sdk is published on Packagist and generated from the same OpenAPI spec that produces this API reference, so it stays in step with the API. PHP 8.2 or later. Requests and responses are typed objects built with named arguments, which keeps calls readable and lets static analysis do its job. ## Installation composer require "kintsugi-tax/tax-platform-sdk" ## Authentication The API authenticates with an API key header. Create a key in the Kintsugi app (see Creating and managing API keys), set it once on the builder, and every call that accepts it is authenticated: declare(strict_types=1); require 'vendor/autoload.php'; use KintsugiTax\SDK; use KintsugiTax\SDK\Models\Components; $sdk = SDK\SDK::builder() ->setSecurity( new Components\Security( apiKeyHeader: '', ) ) ->build(); $response = $sdk->customers->getById( customerId: 'cust_abc123' ); if ($response->customerRead !== null) { // handle response } Response properties are nullable, so a missing body is a null check rather than an exception. A handful of operations take credentials per call rather than per client. The code sample on each API reference page shows a security: argument where that applies, using an operation specific type such as Operations\SearchV1AddressValidationSearchPostSecurity. ## Making a request Request bodies are component objects, and enums are generated cases, so a typo surfaces before the request leaves your process: declare(strict_types=1); require 'vendor/autoload.php'; use KintsugiTax\SDK; use KintsugiTax\SDK\Models\Components; $sdk = SDK\SDK::builder() ->setSecurity( new Components\Security( apiKeyHeader: getenv('KINTSUGI_API_KEY'), ) ) ->build(); $request = new Components\CustomerCreate( name: 'Jane Smith', email: 'jane.smith@example.com', externalId: 'cust_002', street1: '456 Elm St', city: 'Metropolis', state: 'NY', postalCode: '10001', country: Components\CountryCodeEnum::Us, status: Components\StatusEnum::Active, ); $response = $sdk->customers->create( request: $request ); For the exact call on any endpoint, including its component type, arguments and the property the response arrives on, open that endpoint in the API reference and select the PHP tab. ## Error handling An API error throws Errors\APIException, carrying $message, $statusCode, $body and $rawResponse. Operations also declare their own typed exceptions: declare(strict_types=1); require 'vendor/autoload.php'; use KintsugiTax\SDK; use KintsugiTax\SDK\Models\Errors; try { $response = $sdk->customers->getById( customerId: 'cust_abc123' ); if ($response->customerRead !== null) { // handle response } } catch (Errors\ErrorResponseThrowable $e) { // Typed API error echo $e->getMessage(); } catch (Errors\APIException $e) { // Any other HTTP error response echo $e->statusCode . ' ' . $e->body; } Each method's exception table is in the SDK's docs. Error handling covers what the API returns and when a retry is worthwhile. ## Overriding the server URL $sdk = SDK\SDK::builder() ->setServerURL('https://api.trykintsugi.com') ->setSecurity( new Components\Security( apiKeyHeader: getenv('KINTSUGI_API_KEY'), ) ) ->build(); ## Available resources AddressValidation search, suggestions Customers list, create, getById, update, getByExternalId, getTransactions, createTransaction Exemptions list, create, getById, uploadCertificate Exemptions.Attachments get Filings get, getById, getByRegistrationId Nexus listPhysical, createPhysical, updatePhysical, delete, list Products getProductsV1ProductsGet, createProductV1ProductsPost, getProductCategoriesV1ProductsCategoriesGet, get, update Registrations list, create, getById, update, deregister TaxEstimation estimate Transactions list, create, getByExternalId, update, get, getByFilingId, createCreditNote, updateCreditNote PHP SDK repository Source, per-method docs, releases and issues API reference Every endpoint, with a PHP sample on each page --- # Ruby SDK Install, authenticate and call the Kintsugi API from Ruby Source: https://docs.trykintsugi.com/docs/sdks/ruby Official Ruby SDK. kintsugi_sdk is published on RubyGems and generated from the same OpenAPI spec that produces this API reference, so it stays in step with the API. Ruby 3.2 or later. Requests are typed objects from the generated Models namespace, so calls read the same way whichever resource you are working with. The Ruby SDK covers part of the API today: customers, transactions, exemptions, address validation, tax estimation, and some of nexus and products. See Available resources for the current list. For anything outside it, call the endpoint over HTTP. The Ruby tab on those API reference pages shows the Net::HTTP request to send. ## Installation gem install kintsugi_sdk gem 'kintsugi_sdk' ## Authentication The API authenticates with an API key header. Create a key in the Kintsugi app (see Creating and managing API keys), pass it once when you construct the client, and every call that accepts it is authenticated: require 'kintsugi_sdk' Models = ::KintsugiSDK::Models s = ::KintsugiSDK::OpenApiSDK.new( security: Models::Shared::Security.new( api_key_header: '' ) ) req = Models::Ops::GetCustomerByIdV1CustomersCustomerIdGetRequest.new( customer_id: 'cust_abc123' ) res = s.customers.get(request: req) unless res.nil? \# handle response end Each operation takes a request object from Models::Ops, named after the operation. Bodies and shared models live in Models::Shared. A handful of operations take credentials per call rather than per client. The code sample on each API reference page shows a security: argument where that applies, using an operation specific type such as Models::Ops::SearchV1AddressValidationSearchPostSecurity. ## Making a request require 'kintsugi_sdk' Models = ::KintsugiSDK::Models s = ::KintsugiSDK::OpenApiSDK.new( security: Models::Shared::Security.new( api_key_header: ENV.fetch('KINTSUGI_API_KEY') ) ) req = Models::Shared::CustomerCreate.new( name: 'Jane Smith', email: 'jane.smith@example.com', external_id: 'cust_002', street_1: '456 Elm St', city: 'Metropolis', state: 'NY', postal_code: '10001', country: Models::Shared::CountryCodeEnum::US, status: Models::Shared::StatusEnum::ACTIVE ) res = s.customers.create(request: req) For the exact call on any endpoint, including its request type, arguments and what comes back, open that endpoint in the API reference and select the Ruby tab. ## Error handling An API error raises Models::Errors::APIError, carrying message, status_code, body and raw_response. Operations also declare their own typed errors, so rescue those first and fall back to the base class: require 'kintsugi_sdk' Models = ::KintsugiSDK::Models s = ::KintsugiSDK::OpenApiSDK.new( security: Models::Shared::Security.new( api_key_header: ENV.fetch('KINTSUGI_API_KEY') ) ) begin req = Models::Ops::GetCustomerByIdV1CustomersCustomerIdGetRequest.new( customer_id: 'cust_abc123' ) res = s.customers.get(request: req) unless res.nil? \# handle response end rescue Models::Errors::ErrorResponse => e \# Typed API error raise e rescue Models::Errors::APIError => e \# Any other HTTP error response puts "#{e.status_code} #{e.body}" end Each method's error table is in the SDK's docs. Error handling covers what the API returns and when a retry is worthwhile. ## Debug logging Pass debug_logging: true to log the full request and response while you are getting an integration working: s = ::KintsugiSDK::OpenApiSDK.new( debug_logging: true, security: Models::Shared::Security.new( api_key_header: ENV.fetch('KINTSUGI_API_KEY') ) ) Debug output includes request headers and bodies. Keep it off in production so API keys and customer data never reach your logs. ## Overriding the server URL s = ::KintsugiSDK::OpenApiSDK.new( server_url: 'https://api.trykintsugi.com', security: Models::Shared::Security.new( api_key_header: ENV.fetch('KINTSUGI_API_KEY') ) ) ## Available resources AddressValidation search, suggestions Customers list, create, get, update, get_by_external_id, get_transactions, create_transaction Exemptions list, create, get, upload_certificate, get_attachments Nexus list Products get, update TaxEstimation estimate_tax Transactions list, create, get_by_external_id, update, get_by_id, get_by_filing_id Ruby SDK repository Source, per-method docs, releases and issues API reference Every endpoint, with a Ruby sample on each page --- # Getting Started with Kintsugi MCP Learn how AI assistants with Kintsugi MCP help you build better integrations faster Source: https://docs.trykintsugi.com/docs/mcp/getting-started What is MCP? Model Context Protocol (MCP) enables AI coding assistants like Claude in Cursor IDE to understand and use external APIs. Kintsugi's MCP server gives AI assistants direct access to our API documentation, making it easier for developers to build integrations with accurate, up-to-date code examples. Kintsugi's Model Context Protocol (MCP) integration transforms how developers build with our tax compliance API. Instead of manually reading documentation and writing API calls, AI assistants can understand Kintsugi's endpoints, generate accurate code, debug issues, and provide context-aware help, all while you code. ## Why Use Kintsugi MCP? Building integrations with Kintsugi's API typically requires: Reading extensive API documentation Understanding request/response formats Handling authentication correctly Debugging API errors Writing boilerplate code With MCP-enabled AI assistants, you get: Accurate Code Generation - AI understands Kintsugi's actual API endpoints and generates working code Real-Time Documentation - AI assistants access up-to-date API specs, not outdated docs Context-Aware Help - Get suggestions based on your actual code and integration needs Faster Development - Reduce time spent on API integration from hours to minutes Example: Building a Checkout Integration You: "How do I calculate tax for a checkout using Kintsugi?" AI Assistant (with Kintsugi MCP): Understands the /v1/tax/estimate endpoint Generates code with correct request format Includes proper authentication headers Handles response parsing Result: You get working code to integrate tax calculation into your checkout flow. Example: Debugging API Issues You: "My tax calculation is failing with a 400 error" AI Assistant (with Kintsugi MCP): Tests the same endpoint with your parameters Identifies missing required fields Suggests fixes based on current API requirements Provides corrected code Result: Fast resolution instead of manual API debugging. Example: Understanding Complex Workflows You: "How do I handle tax-exempt customers in my integration?" AI Assistant (with Kintsugi MCP): Explains exemption endpoints Shows how to link exemptions to transactions Generates code for the complete workflow Provides best practices Result: Complete understanding and implementation in one conversation. ## How It Works Here's how Kintsugi MCP helps you build better integrations: 01 You ask a question Your side “How do I calculate tax for a checkout using Kintsugi?” 02 Your assistant queries over MCP AI assistant Cursor, Claude Desktop, or VS Code with an MCP extension. 03 The Kintsugi MCP server reads the spec Kintsugi docs.trykintsugi.com/mcp round trip Requests openapi.json — the live spec, never a stale copy of the docs Returns endpoints, request and response schemas, and auth requirements Repeats whenever the assistant needs more of the spec 04 It writes code against the real API AI assistant POST https://api.trykintsugi.com/v1/tax/estimate x-api-key: your-api-key x-organization-id: your-org-id { "amount": 100.00, "shipping_address": { … } } 05 Your integration calls the API Your side api.trykintsugi.com runtime Sends the cart total and shipping address over HTTPS with your keys Returns the tax amount and the jurisdiction breakdown 06 Integration complete Your side Working tax calculation in minutes, not an afternoon of reading docs. The MCP server explains the API; you still need valid credentials to call it. 1. Developer Asks Question You ask an AI assistant: "How do I call Kintsugi's tax estimation endpoint?" 2. AI Queries MCP Server The AI assistant queries Kintsugi's MCP server, which provides access to our OpenAPI specification with all endpoint details. 3. AI Understands API Structure The MCP server gives the AI context about: Available endpoints (like POST /v1/tax/estimate) Request/response schemas Authentication requirements Error handling patterns 4. AI Generates Accurate Code Based on the API spec, the AI generates working code: import requests ## How It Works response = requests.post( 'https://api.trykintsugi.com/v1/tax/estimate', headers={ 'x-api-key': 'your-api-key', 'x-organization-id': 'your-org-id' }, json={ 'amount': 100.00, 'shipping_address': {...} } ) 5. Developer Uses Code You integrate the generated code into your application, customize it for your needs, and start making API calls. ## Quick Setup Choose Your Development Environment Kintsugi MCP works with MCP-compatible AI coding assistants: Cursor IDE Cursor's AI assistant can use MCP servers, making it perfect for developers building Kintsugi integrations. The AI understands your codebase and Kintsugi's API simultaneously. Claude Desktop Claude Desktop supports MCP servers and can help with API integration code, even outside an IDE. VS Code with MCP Extension VS Code extensions that support MCP can connect to Kintsugi's MCP server for API-aware code assistance. Configure MCP Server Add Kintsugi's MCP server to your AI assistant configuration: { "mcpServers": { "kintsugi": { "url": "https://docs.trykintsugi.com/mcp", "headers": { "X-API-KEY": "your-api-key", "X-ORGANIZATION-ID": "your-org-id" } } } } Get Your API Key & Organization ID You'll need both an API key and Organization ID for authentication: Sign in to app.trykintsugi.com From the sidebar (bottom-left), open Configuration → API Keys Create a new API key Store it securely (never commit to version control) Find your Organization ID in the lower left-hand corner of the dashboard after logging in Paste both into the headers block of the config above. The server reads your key from the connection headers, so a config with only a url lists the tools but cannot call them. Start Building Once configured, your AI assistant understands Kintsugi's API. Try asking: "Show me how to estimate tax for a transaction" "Generate code to create a customer in Kintsugi" "How do I handle address validation?" "What's the request format for creating a registration?" ## What the tools can do Each tool maps to one Customer API operation and is named after its reference page, so create-transaction the tool and /reference/create-transaction the page are always the same operation. The tools do not only describe the API, they call it, with the key from your connection headers. That means 17 of the 41 change your data: creating a transaction or a credit note, updating a customer, deregistering a registration, deleting a physical nexus. The other 24 only read. That includes three that are POST requests but commit nothing, because they take a request body rather than because they save anything: estimate-tax, search and suggestions. Every tool that writes is marked read-only-false in its MCP annotations, and destructive deletes are marked as such, so a well-behaved client asks you before running one. Not every client surfaces those prompts, so treat the key you configure here as one an AI assistant can act with on your behalf. Kintsugi API keys are not scoped: a key grants the access its organization has, and there is no read-only variant to hand out instead. So if you want to try the tools against data you do not mind changing, use a key from a test organization rather than your production one, and revoke it when you are done. Read-only operations (anything beginning get-) only fetch. Kintsugi validates every call against the published schema before it reaches the API, and any error the API returns is passed back to you unchanged. ## Available API Endpoints Kintsugi MCP on the public docs site exposes endpoints from the public API Reference only (the Customer API). Partner APIs are not included. Tax Estimation POST /v1/tax/estimate - Calculate tax for transactions before committing Transaction Management POST /v1/transactions, GET /v1/transactions - Create and manage sales transactions Customer Management POST /v1/customers, GET /v1/customers/{customer_id} - Manage customer records Nexus & Registrations GET /v1/nexus, POST /v1/registrations - Determine nexus and manage registrations Products & Categories POST /v1/products, GET /v1/products/categories - Manage product taxability Filings & Compliance GET /v1/filings - Track and manage tax filings Address Validation POST /v1/address_validation/search - Validate addresses for accurate tax calculation Exemptions POST /v1/exemptions, GET /v1/exemptions - Manage tax exemption certificates ## Real-World Example Here's a complete example of building a checkout integration with MCP: Developer: "I need to add tax calculation to my e-commerce checkout. How do I integrate with Kintsugi?" AI Assistant (with Kintsugi MCP): Understands the requirement - Needs tax calculation in checkout flow Identifies the endpoint - POST /v1/tax/estimate from Kintsugi's API Generates code: import requests def calculate_tax(cart_total, shipping_address, api_key, organization_id): response = requests.post( 'https://api.trykintsugi.com/v1/tax/estimate', headers={ 'x-api-key': api_key, 'x-organization-id': organization_id, 'Content-Type': 'application/json' }, json={ 'amount': cart_total, 'shipping_address': { 'street_1': shipping_address['street'], 'city': shipping_address['city'], 'state': shipping_address['state'], 'zip': shipping_address['zip'] } } ) response.raise_for_status() return response.json() Explains next steps - How to handle the response, error cases, and commit the transaction Result: Developer has working code in minutes instead of hours of API documentation reading. ## Benefits for Developers Faster Integration Reduce integration time from days to hours with AI-generated code Fewer Errors AI understands API schemas and generates correct request formats Always Up-to-Date MCP provides current API specs, not outdated documentation Better Debugging AI can test endpoints and identify issues faster than manual debugging ## Next Steps Explore Use Cases See how developers use Kintsugi MCP in real projects Integration Guide Step-by-step setup for your development environment Official SDKs Python, TypeScript, Java, PHP, and Ruby clients Full API Reference Complete API documentation Authentication Required - While the MCP server helps AI assistants understand Kintsugi's API, you'll still need valid API credentials to make actual API calls. Kintsugi uses API key authentication via headers (not bearer token). Every request requires: x-api-key header with your API key x-organization-id header with your organization ID Generate API keys in your Kintsugi dashboard. Your Organization ID can be found in the lower left-hand corner after logging in. --- # Use Cases and Examples Real-world examples of developers using Kintsugi MCP to build integrations faster Source: https://docs.trykintsugi.com/docs/mcp/use-cases This guide showcases how developers use Kintsugi MCP to build integrations more efficiently. From e-commerce checkouts to compliance automation, see how AI assistants with MCP understanding help write better code faster. E-Commerce Integration Build tax calculation into checkout flows API Debugging Quickly identify and fix API integration issues Complex Workflows Implement multi-step tax compliance processes Code Generation Generate boilerplate and integration code ## E-Commerce Checkout Integration One of the most common use cases: adding tax calculation to an e-commerce checkout flow. Developer Workflow Developer: "I need to add tax calculations to my custom store's checkout. How do I integrate Kintsugi?" AI Assistant (with Kintsugi MCP): Understands the context - E-commerce checkout needs real-time tax calculation Identifies the endpoint - POST /v1/tax/estimate from Kintsugi's API Generates integration code: \# Generated by AI with Kintsugi MCP understanding from flask import Flask, request, jsonify import requests app = Flask(__name__) KINTSUGI_API_KEY = os.getenv('KINTSUGI_API_KEY') KINTSUGI_API_URL = 'https://api.trykintsugi.com' @app.route('/api/checkout/calculate-tax', methods=['POST']) def calculate_tax(): cart_data = request.json \# Prepare tax estimation request tax_request = { 'amount': cart_data['subtotal'], 'shipping_address': { 'street_1': cart_data['shipping']['address1'], 'street_2': cart_data['shipping'].get('address2'), 'city': cart_data['shipping']['city'], 'state': cart_data['shipping']['province_code'], 'zip': cart_data['shipping']['zip'] }, 'line_items': [ { 'product_id': item['product_id'], 'quantity': item['quantity'], 'price': item['price'] } for item in cart_data['items'] ] } \# Call Kintsugi API response = requests.post( f'{KINTSUGI_API_URL}/v1/tax/estimate', headers={ 'x-api-key': KINTSUGI_API_KEY, 'x-organization-id': ORGANIZATION_ID, 'Content-Type': 'application/json' }, json=tax_request ) if response.status_code == 200: tax_data = response.json() return jsonify({ 'tax_amount': tax_data['tax_amount'], 'total': cart_data['subtotal'] + tax_data['tax_amount'], 'breakdown': tax_data.get('breakdown', []) }) else: return jsonify({'error': 'Tax calculation failed'}), response.status_code ## E-Commerce Checkout Integration Explains the flow - How to handle the response, store transactions, and commit tax Key Benefits Accurate Request Format AI understands the exact schema required by Kintsugi's API, generating correct request structures without manual documentation lookup. Error Handling AI includes proper error handling based on Kintsugi's API error patterns, reducing debugging time. Best Practices Generated code follows Kintsugi's recommended patterns for authentication, request formatting, and response handling. ## API Debugging and Troubleshooting When API calls fail, MCP-enabled AI assistants can help debug faster than manual investigation. Example: Debugging Failed Tax Calculation Developer: "My tax calculation is returning a 400 error. Here's my code:" response = requests.post( 'https://api.trykintsugi.com/v1/tax/estimate', headers={ 'x-api-key': api_key, 'x-organization-id': organization_id }, json={'amount': 100, 'address': 'Seattle, WA'} ) AI Assistant (with Kintsugi MCP): Tests the endpoint - Uses MCP to understand required parameters Identifies the issue - The request is missing required fields Provides fix: \# Fixed code based on actual API schema response = requests.post( 'https://api.trykintsugi.com/v1/tax/estimate', headers={ 'x-api-key': api_key, 'x-organization-id': organization_id, 'Content-Type': 'application/json' }, json={ 'amount': 100.00, 'shipping_address': { # Required field name 'street_1': '123 Main St', # Required 'city': 'Seattle', # Required 'state': 'WA', # Required 'zip': '98101' # Required } } ) Explains the error - Why address string format isn't supported, needs structured object Debugging Workflow 01 You paste the error and the code Your side 422 Unprocessable Entity “my POST /v1/transactions keeps failing — here’s the payload” 02 Your assistant reads the request AI assistant It parses your payload before guessing at the cause. 03 It pulls the schema from the MCP server Kintsugi docs.trykintsugi.com/mcp round trip Asks for the schema behind POST /v1/transactions Returns required fields, types, and accepted enum values 04 It compares your code with the schema AI assistant Missing required fields Wrong formats Invalid values 05 You get corrected code AI assistant POST /v1/transactions { "date": "2026-07-29", // was 07/29/2026 ## API Debugging and Troubleshooting "currency": "USD", // was missing "addresses": [ … ] } 06 Plus the reason it failed Your side Every change cites the schema field behind it. If the next error appears, paste it and the loop repeats against a fresh spec. The MCP server describes the API; it never sees your keys or your customer data. ## Complex Multi-Step Workflows Building complete tax compliance workflows often involves multiple API calls. MCP helps AI assistants understand the entire flow. Example: Customer Exemption Workflow Developer: "How do I handle tax-exempt customers? I need to check if they have an exemption, apply it to transactions, and store the exemption certificate." AI Assistant (with Kintsugi MCP): Understands the workflow - Multiple endpoints involved Generates complete implementation: class TaxExemptHandler: def __init__(self, api_key, organization_id): self.api_key = api_key self.organization_id = organization_id self.base_url = 'https://api.trykintsugi.com' def check_customer_exemption(self, customer_id): """Check if customer has active exemption""" response = requests.get( f'{self.base_url}/v1/customers/{customer_id}/exemptions', headers={ 'x-api-key': self.api_key, 'x-organization-id': self.organization_id } ) response.raise_for_status() exemptions = response.json() \# Return active exemption if exists active = [e for e in exemptions if e['status'] == 'active'] return active[0] if active else None def upload_exemption_certificate(self, customer_id, certificate_file): """Upload exemption certificate for customer""" with open(certificate_file, 'rb') as f: files = {'file': f} data = {'customer_id': customer_id} response = requests.post( f'{self.base_url}/v1/exemptions/upload', headers={ 'x-api-key': self.api_key, 'x-organization-id': self.organization_id }, files=files, data=data ) response.raise_for_status() return response.json() def create_transaction_with_exemption(self, transaction_data, exemption_id): """Create transaction with exemption applied""" transaction_data['exemption_id'] = exemption_id ## Complex Multi-Step Workflows response = requests.post( f'{self.base_url}/v1/transactions', headers={ 'x-api-key': self.api_key, 'x-organization-id': self.organization_id, 'Content-Type': 'application/json' }, json=transaction_data ) response.raise_for_status() return response.json() Explains the workflow: Step 1: Check for existing exemption Step 2: Upload certificate if needed Step 3: Link exemption to transaction Step 4: Handle edge cases (expired exemptions, invalid certificates) Workflow Diagram Developer Your application Kintsugi API 01 Checkout starts Developer A checkout request reaches your application with the customer ID attached. 02 Your app checks exemption status Application api.trykintsugi.com lookup GET /v1/customers/{id}/exemptions Returns the exemption status for that customer 03 The status decides the path Application A Active exemption on file POST /v1/transactions Transaction created with tax = 0 B Exemption still needed POST /v1/exemptions/upload Exemption created, returns an exemption_id POST /v1/transactions Transaction created Both paths send the same exemption_id on the transaction. 04 Checkout completes Developer The customer is charged the correct tax and the exemption is recorded against the transaction. ## Code Generation and Boilerplate Reduce repetitive code by having AI generate complete integration modules. Example: Complete SDK Wrapper Developer: "Generate a Python SDK wrapper for Kintsugi's main endpoints" AI Assistant (with Kintsugi MCP): Generates a complete, production-ready SDK: import requests from typing import Optional, Dict, List class KintsugiClient: def __init__(self, api_key: str, organization_id: str, base_url: str = 'https://api.trykintsugi.com'): self.api_key = api_key self.organization_id = organization_id self.base_url = base_url self.session = requests.Session() self.session.headers.update({ 'x-api-key': api_key, 'x-organization-id': organization_id, 'Content-Type': 'application/json' }) def estimate_tax(self, amount: float, shipping_address: Dict, line_items: Optional[List[Dict]] = None) -> Dict: """Estimate tax for a transaction""" payload = { 'amount': amount, 'shipping_address': shipping_address } if line_items: payload['line_items'] = line_items response = self.session.post( f'{self.base_url}/v1/tax/estimate', json=payload ) response.raise_for_status() return response.json() def create_transaction(self, transaction_data: Dict) -> Dict: """Create a new transaction""" response = self.session.post( f'{self.base_url}/v1/transactions', json=transaction_data ) response.raise_for_status() return response.json() def get_customer(self, customer_id: str) -> Dict: """Get customer by ID""" response = self.session.get( f'{self.base_url}/v1/customers/{customer_id}' ) response.raise_for_status() return response.json() \# ... more methods generated based on API endpoints Result: Complete, typed, production-ready SDK in minutes instead of hours of manual implementation. ## Integration Testing MCP helps generate comprehensive test suites for Kintsugi integrations. Example: Test Suite Generation Developer: "Generate tests for my Kintsugi tax calculation integration" AI Assistant (with Kintsugi MCP): Generates test cases covering: Successful tax calculation Invalid address handling Missing required fields Authentication errors Rate limiting scenarios import pytest from unittest.mock import Mock, patch from your_app import TaxCalculator class TestTaxCalculation: @patch('requests.post') def test_successful_tax_calculation(self, mock_post): \# Mock successful API response based on actual schema mock_post.return_value.status_code = 200 mock_post.return_value.json.return_value = { 'tax_amount': 10.00, 'tax_rate': 0.10, 'breakdown': [...] } calculator = TaxCalculator(api_key='test-key') result = calculator.calculate(100.00, {'city': 'Seattle', 'state': 'WA'}) assert result['tax_amount'] == 10.00 mock_post.assert_called_once() def test_invalid_address_handling(self): \# Test cases for various address validation scenarios ... ## Next Steps Getting Started Learn the basics of using Kintsugi MCP Integration Guide Set up MCP in your development environment Official SDKs Python, TypeScript, Java, PHP, and Ruby clients API Reference Complete API documentation Your Use Case - These examples show common patterns, but Kintsugi MCP can help with any integration scenario. Whether you're building webhooks, batch processing, or complex compliance workflows, AI assistants with MCP understanding can accelerate your development. --- # Integration Guide Set up Kintsugi MCP in your development environment to build integrations faster Source: https://docs.trykintsugi.com/docs/mcp/integration This guide walks you through setting up Kintsugi MCP in your development environment. Once configured, your AI coding assistant can search Kintsugi's docs and the live OpenAPI spec directly, so it writes integration code against the current API instead of a stale copy of the reference. ## Prerequisites Choose an MCP-capable AI coding assistant: Cursor IDE (recommended - built-in MCP support) Claude Desktop (for general API help) VS Code (through GitHub Copilot Chat's agent mode, or another MCP-capable extension) MCP doesn't need your API key. The Kintsugi MCP server only reads public Kintsugi docs and the OpenAPI spec — it never proxies calls to the API and never sees your credentials. You'll need an API key and Organization ID later, when you run the code your assistant generates against the real API. See Creating and Managing API Keys when you're ready. ## Cursor IDE Setup Cursor has built-in MCP support. Configuration is a JSON file — there's no wizard. Create or open the Cursor MCP config Cursor reads MCP servers from two places (both use the same schema): Global: ~/.cursor/mcp.json — available in every project Per-project: .cursor/mcp.json in the project root Create the file if it doesn't exist. You can also open it from Cursor Settings → Tools & MCPs. Add the Kintsugi MCP server { "mcpServers": { "kintsugi": { "url": "https://docs.trykintsugi.com/mcp", "headers": { "X-API-KEY": "your-api-key", "X-ORGANIZATION-ID": "your-org-id" } } } } If the file already has other servers, add kintsugi alongside them inside the existing mcpServers object. Reload Cursor Cursor picks up changes to mcp.json on save. If it doesn't, restart Cursor. Verify setup Open Cursor's AI chat and ask: "What Kintsugi API endpoints are available for tax estimation?" "Show me the request format for creating a transaction" The assistant should search the Kintsugi docs via MCP and cite real endpoints. Using Kintsugi MCP in Cursor Once configured, here's how to use it: Code Generation You: "Generate code to calculate tax using Kintsugi API" Cursor: Searches Kintsugi's docs via MCP, finds POST /v1/tax/estimate, and generates working code with the correct request format and headers. API Documentation You: "What parameters does the create transaction endpoint need?" Cursor: Reads the current OpenAPI spec via MCP and lists required and optional fields with types. Debugging You: "Why is my tax calculation failing?" (shows code) Cursor: Pulls the current schema via MCP and points out fields that don't match. Refactoring You: "Refactor this to use Kintsugi's customer endpoint properly" ## Cursor IDE Setup Cursor: Uses the docs to align your code with the current customer API shape. ## Claude Desktop Setup Claude Desktop supports remote MCP servers from the config file below. If you're on an older version of Claude Desktop, you may need to run claude mcp add from the CLI or wrap the server with the mcp-remote proxy instead. Locate Config File Find your Claude Desktop configuration file: macOS ~/Library/Application Support/Claude/claude_desktop_config.json Windows %APPDATA%\Claude\claude_desktop_config.json Linux ~/.config/Claude/claude_desktop_config.json Edit Configuration Open the config file and add Kintsugi MCP: { "mcpServers": { "kintsugi": { "url": "https://docs.trykintsugi.com/mcp", "headers": { "X-API-KEY": "your-api-key", "X-ORGANIZATION-ID": "your-org-id" } } } } If the file doesn't exist, create it with this structure. If it already has mcpServers, add kintsugi to the existing object. Restart Claude Desktop Close and reopen Claude Desktop so it re-reads the config file. Test the integration Ask Claude: "What Kintsugi API endpoints can help me build a checkout integration?" Claude should search the Kintsugi docs and cite real endpoints. ## VS Code Setup VS Code has built-in MCP support through GitHub Copilot Chat (agent mode). If you use a different chat extension with MCP support, the same JSON works. Add the Kintsugi MCP server Create .vscode/mcp.json in your project: { "servers": { "kintsugi": { "type": "http", "url": "https://docs.trykintsugi.com/mcp", "headers": { "X-API-KEY": "your-api-key", "X-ORGANIZATION-ID": "your-org-id" } } } } Or add the same block under "mcp" in your VS Code user settings.json if you want it available in every workspace. VS Code's MCP config uses servers (not mcpServers) and adds a type field. That's a VS Code quirk — Cursor and Claude Desktop use the shape shown further up. Ask Copilot Chat Open Copilot Chat, switch to Agent mode, and ask: "What Kintsugi endpoints are available for tax estimation?" Copilot will call into MCP to answer. ## Custom MCP Client Setup For advanced use cases, you can build your own MCP client on top of the official SDK. Basic MCP Client Example The Kintsugi MCP server speaks Streamable HTTP and exposes one tool per Customer API operation, named after its reference page ( create-transaction, get-transactions, and so on). Each tool calls the API with the key you send in the connection headers. import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; const transport = new StreamableHTTPClientTransport( new URL('https://docs.trykintsugi.com/mcp'), { requestInit: { headers: { 'X-API-KEY': process.env.KINTSUGI_API_KEY, 'X-ORGANIZATION-ID': process.env.KINTSUGI_ORGANIZATION_ID, }, }, } ); const client = new Client({ name: 'kintsugi-dev-tool', version: '1.0.0', }); await client.connect(transport); // Discover what the server exposes const { tools } = await client.listTools(); console.log('Tools:', tools.map((t) => t.name)); // -> ['search_kintsugi', 'query_docs_filesystem_kintsugi'] // Search the docs (returns matching pages with links and excerpts) const result = await client.callTool({ name: 'search_kintsugi', arguments: { query: 'POST /v1/tax/estimate request schema' }, }); console.log(result); Integrating into Development Tools You can build on Kintsugi MCP to power: Code generators - Pull the current spec at build time and regenerate clients API testing tools - Auto-generate test cases from the docs Documentation generators - Mirror the API reference into internal docs Custom IDE plugins - Build specialized tools for your team ## Verification and Testing After setup, verify your MCP integration works correctly. Test 1: Endpoint discovery Ask your AI: "What Kintsugi endpoints are available for tax calculation?" Expected: The assistant lists relevant endpoints like /v1/tax/estimate and cites the docs page it found them on. Test 2: Code generation Ask your AI: "Generate Python code to call Kintsugi's tax estimation endpoint" Expected: Working code with: The correct endpoint URL Both x-api-key and x-organization-id headers Payload fields that match the current schema Test 3: Schema understanding Ask your AI: "What's the request schema for creating a transaction in Kintsugi?" Expected: A field-by-field breakdown pulled from the current OpenAPI spec — required vs. optional, field types, and any enum values. Test 4: Debugging help Show code with an error: "Why isn't this working?" (code that's missing required fields) Expected: The assistant pulls the current schema via MCP and points out the specific fields that are missing or wrong. ## Best Practices Use for Code Generation Let MCP generate boilerplate against the current spec, then review and customize for your app. Keep API Keys Secure Your API key and Organization ID belong in your application's runtime — never in your MCP config, never in generated code committed to a repo. Use environment variables or a secret manager. Both x-api-key and x-organization-id are required on every API call. Verify Generated Code Always test AI-generated code before deploying. MCP gives the assistant the current schema, but you still own the behaviour. Prefer MCP over stale references If you have both the docs open in a browser and MCP configured, trust the answer MCP returns — it reads the live spec, so it stays current when the API changes. ## Troubleshooting AI Doesn't Understand Kintsugi API Confirm your MCP client actually loaded the config — most clients list their MCP servers somewhere in settings. Check the URL is exactly https://docs.trykintsugi.com/mcp. Verify the JSON is valid (a stray comma will silently disable the whole block). Restart the client if the change was made while it was running. Tools return "No Kintsugi API key was sent with this request" The server reads your key from the connection headers, not from the tool arguments, so a config with only a url will list all the tools but cannot call any of them. Add a headers block with X-API-KEY alongside the url (see the setup steps above). Add X-ORGANIZATION-ID too if your key spans more than one organization. Restart the client: most read headers only when the connection is first opened. A call is refused with 401 or 403 The key reached the API and the API rejected it. The MCP server does not validate keys itself, so the status and message you see are the API's own. Check the key is active under Configuration → API Keys in the dashboard. Confirm you copied the whole value, with no trailing whitespace. See Authentication for what the API expects. Generated Code Has Errors Ask the assistant to re-pull the schema before generating (some clients cache tool results). Verify both x-api-key and x-organization-id headers are set in your runtime. Confirm the base URL: https://api.trykintsugi.com. Test the call with curl to isolate whether the bug is in the generated code or in the environment. MCP Server Not Responding Confirm outbound HTTPS to docs.trykintsugi.com isn't blocked by a firewall or proxy. The endpoint is JSON-RPC over Streamable HTTP — a browser GET is not a valid health check. ## Troubleshooting Check the client's MCP log; most clients surface tool-call errors there. ## Next Steps Getting Started Learn how MCP helps you build integrations Use Cases See real-world examples and workflows Official SDKs Python, TypeScript, Java, PHP, and Ruby clients API Reference Complete API documentation Ready to Build? Once MCP is configured, ask your AI assistant for any Kintsugi integration and it will pull the current spec to generate the right code. --- # API Lab Interactive, runnable walkthroughs for the Kintsugi API. Source: https://docs.trykintsugi.com/docs/recipes Each recipe is a hands-on walkthrough of a common Kintsugi workflow. Open one to step through the calls, edit the requests, and see the responses. Estimate Tax Calculate tax for a transaction before you commit it, using live inputs for addresses, products, and exemptions. Open API Lab → Managing Products Create products, fetch categories, and retrieve product details so items are classified correctly for tax. Open API Lab → Managing Customers Create customer records and look them up. The foundation for exemptions and customer-level reporting. Open API Lab → Creating Transactions Record completed sales and retrieve them, keeping your compliance data in sync with every order. Open API Lab → Creating Credit Notes Issue credit notes for refunds and returns so your sales records stay accurate. Open API Lab → Managing Nexus Create physical nexus and registrations, then confirm where your business has tax obligations. Open API Lab → --- # Calculate Tax for a Transaction Interactive walkthrough to calculate tax using the Kintsugi API Source: https://docs.trykintsugi.com/docs/recipes/calculate-tax ## Overview The Tax Estimation API calculates the estimated tax for a transaction based on your organization's nexus status, product taxability, customer exemptions, and shipping addresses. This endpoint is idempotent and doesn't create permanent transaction records, making it perfect for testing tax calculations during checkout flows. ## When to Use Shopping cart pages: Calculate tax when customers review their order Checkout flows: After address entry but before payment processing Subscription billing: Calculate tax for recurring charges Quote generation: Provide tax estimates to customers ## Authentication This endpoint requires two headers: x-api-key: Your API key x-organization-id: Your organization ID Both headers are required for authentication. You can find your API key and organization ID in your Kintsugi dashboard. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Estimate tax POST /v1/tax/estimate Edit the addresses, line items, or exemptions to shape the request. Because this lab is simulated, the returned figures are illustrative rather than live jurisdiction rates. { "date": "2025-01-23T13:01:29.949Z", "external_id": "txn_12345", "currency": "USD", "addresses": [ { "type": "SHIP_TO", "street_1": "789 Pine St", "city": "Austin", "state": "TX", "postal_code": "78701", "country": "US" } ], "transaction_items": [ { "external_id": "item_A", "date": "2024-10-28T10:00:00Z", "external_product_id": "prod_abc", "quantity": 2, "amount": 100 }, { "external_id": "item_B", "date": "2024-10-28T10:00:00Z", "external_product_id": "prod_xyz", "quantity": 1, "amount": 75.5, "is_tax_inclusive": false } ] } { "date": "2025-01-23T13:01:29.949Z", "external_id": "txn_12345", "currency": "USD", "addresses": [ { "type": "SHIP_TO", "street_1": "789 Pine St", "city": "Austin", "state": "TX", "postal_code": "78701", "country": "US" } ], "transaction_items": [ { "external_id": "item_A", "date": "2024-10-28T10:00:00Z", "external_product_id": "prod_abc", "quantity": 2, "amount": 100 }, { "external_id": "item_B", "date": "2024-10-28T10:00:00Z", "external_product_id": "prod_xyz", "quantity": 1, "amount": 75.5, "is_tax_inclusive": false } ] } Run ## Required Fields date: Transaction date in ISO 8601 format external_id: Your unique identifier for the transaction currency: Three-letter currency code (for example, USD) addresses: One or more addresses; the ship-to address determines the tax jurisdiction transaction_items: The line items to price, each with an amount ## Common Use Cases Basic Tax Calculation Calculate tax for a simple transaction with a shipping address: { "date": "2024-01-15T10:00:00Z", "external_id": "order-123", "currency": "USD", "source": "API", "transaction_items": [ { "external_id": "item-1", "external_product_id": "product-123", "product_name": "Example Product", "quantity": "1.0", "amount": 100.00 } ], "addresses": [ { "type": "SHIP_TO", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } ] } With Customer Information Include customer details to check for exemptions: { "date": "2024-01-15T10:00:00Z", "external_id": "order-123", "currency": "USD", "source": "API", "customer": { "name": "John Doe", "email": "john@example.com", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" }, "transaction_items": [ { "external_id": "item-1", "external_product_id": "product-123", "product_name": "Example Product", "quantity": "1.0", "amount": 100.00 } ], "addresses": [ { "type": "SHIP_TO", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } ] } ## Response Fields total_tax_amount_calculated: Total tax calculated for the transaction taxable_amount: Amount subject to tax tax_rate_calculated: Overall tax rate applied nexus_met: Whether your organization has nexus in the destination jurisdiction has_active_registration: Whether you have an active registration there ## Next Steps Create a Transaction - Record the transaction after payment Sales Tax Calculations Guide - Learn more about tax calculation Getting Started - Set up your integration ## Related Resources Tax Estimation API Reference Sales Tax for Developers Support --- # Create a Product Interactive walkthrough to create products using the Kintsugi API Source: https://docs.trykintsugi.com/docs/recipes/managing-products ## Overview Products in Kintsugi represent the items you sell. Each product needs proper tax classification (category and subcategory) to ensure accurate tax calculations. This endpoint creates a new product record that will be used for tax calculations in transactions. ## When to Use Product catalog setup: Create products when setting up your integration New product launches: Add new products as you expand your catalog Tax classification: Ensure products have proper tax categories for accurate calculations Manual product management: Create products outside of automated syncs ## Authentication This endpoint requires two headers: x-api-key: Your API key x-organization-id: Your organization ID Both headers are required for authentication. You can find your API key and organization ID in your Kintsugi dashboard. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create product POST /v1/products { "external_id": "prod_001", "name": "T-shirts", "description": "Common items of everyday wearing apparel designed for human use, covering a wide variety of non-specialized garments.", "status": "APPROVED", "product_category": "Physical", "product_subcategory": "General Clothing", "tax_exempt": false, "source": "BIGCOMMERCE" } { "external_id": "prod_001", "name": "T-shirts", "description": "Common items of everyday wearing apparel designed for human use, covering a wide variety of non-specialized garments.", "status": "APPROVED", "product_category": "Physical", "product_subcategory": "General Clothing", "tax_exempt": false, "source": "BIGCOMMERCE" } Run 2 Get product categories GET /v1/products/categories Browse the categories you can assign to a product. Run 3 Get product by id GET /v1/products/{product_id} Run Run the previous step to fill the path. ## Required Fields external_id: Your internal product identifier (must be unique within your organization) name: Name of the product product_category: Product category (see Get Product Categories) product_subcategory: Product subcategory (see Get Product Categories) ## Common Use Cases Basic Product Creation Create a product with minimal required fields: { "external_id": "SKU-12345", "name": "Example Product", "product_category": "Physical", "product_subcategory": "General Physical" } Product with Full Details Include additional product information: { "external_id": "PROD-ABC-123", "name": "Premium Wireless Headphones", "product_category": "Physical", "product_subcategory": "General Physical", "description": "High-quality wireless headphones with noise cancellation", "source": "API" } ## Response Fields id: Kintsugi's unique product identifier external_id: Your product identifier name: Product name product_category: Product category product_subcategory: Product subcategory status: Product status (ACTIVE, ARCHIVED) tax_exempt: Whether the product is tax exempt source: Source of the product record ## Product Categories Before creating products, you may want to fetch available categories and subcategories using the Get Product Categories endpoint. Categories determine how products are taxed across different jurisdictions. Product categories align with tax regulations across jurisdictions. Choose the most specific category and subcategory that matches your product to ensure accurate tax calculations. ## Next Steps Get Product Categories - View all available categories and subcategories Get Products - List and search your products Get Product by ID - Retrieve a specific product Update Product - Modify product details Product & Customer Records Guide - Learn more about product management ## Related Resources Products API Reference Getting Started Support --- # Managing Customers Interactive walkthrough for creating customers and retrieving customer records Source: https://docs.trykintsugi.com/docs/recipes/managing-customers ## Overview Customer records in Kintsugi store customer information and enable exemption management. While not required for all integrations, customer records are essential when dealing with tax-exempt customers (nonprofits, resellers, etc.) or when you need to track customer-specific tax information. ## When to Create Customer Records Tax-exempt customers: Nonprofits, resellers, or other exempt entities Customer exemptions: When customers have jurisdiction-specific exemptions Customer tracking: When you need to maintain customer tax history For regular taxable customers, you can pass customer information directly in transaction requests without creating separate customer records. ## Workflow Create a Customer - Create a customer record with address information Retrieve Customers - Search and retrieve customer records ## Step 1: Create a Customer Create a customer record using the API Lab below with POST /v1/customers. Example Request { "external_id": "CUST-001", "name": "Acme Corporation", "email": "contact@acme.com", "street_1": "123 Business St", "city": "San Francisco", "state": "CA", "postal_code": "94105", "country": "US" } ## Step 2: Retrieve Customers After creating customers, retrieve them using GET /v1/customers. You can: Search by external_id using the search_query parameter Filter by country and state Paginate through all customers ## Authentication This endpoint requires two headers: x-api-key: Your API key x-organization-id: Your organization ID Both headers are required for authentication. You can find your API key and organization ID in your Kintsugi dashboard. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create customer POST /v1/customers Send a customer record. The response returns the new customer, including its id. { "phone": "987-654-3210", "street_1": "456 Elm St", "street_2": "Suite 202", "city": "Metropolis", "county": "Wayne", "state": "NY", "postal_code": "10001", "country": "US", "name": "Jane Smith", "external_id": "cust_002", "status": "ARCHIVED", "email": "jane.smith@example.com", "source": "SHOPIFY", "address_status": "PARTIALLY_VERIFIED" } { "phone": "987-654-3210", "street_1": "456 Elm St", "street_2": "Suite 202", "city": "Metropolis", "county": "Wayne", "state": "NY", "postal_code": "10001", "country": "US", "name": "Jane Smith", "external_id": "cust_002", "status": "ARCHIVED", "email": "jane.smith@example.com", "source": "SHOPIFY", "address_status": "PARTIALLY_VERIFIED" } Run 2 Get customer by id GET /v1/customers/{customer_id} Fetch the customer you just created. The id from step 1 fills the path automatically. Run Run the previous step to fill the path. ## Required Fields external_id: Your internal customer identifier (must be unique within your organization) name: Customer name email: Customer email address ## Common Use Cases Basic Customer Creation Create a customer with minimal required fields: { "external_id": "CUST-12345", "name": "John Doe", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } Customer with Full Details Include complete customer information: { "external_id": "CUST-ABC-123", "name": "Acme Corporation", "email": "contact@acme.com", "phone": "555-123-4567", "street_1": "123 Business St", "street_2": "Suite 100", "city": "San Francisco", "county": "San Francisco", "state": "CA", "postal_code": "94105", "country": "US", "source": "API" } Exempt Customer Create a customer that may be tax-exempt: { "external_id": "CUST-NONPROFIT-001", "name": "Nonprofit Organization", "email": "info@nonprofit.org", "street_1": "456 Charity Ave", "city": "Austin", "state": "TX", "postal_code": "78701", "country": "US", "status": "ACTIVE" } ## Response Fields id: Kintsugi's unique customer identifier external_id: Your customer identifier name: Customer name email: Customer email status: Customer status (ACTIVE, ARCHIVED) address_status: Address verification status ## Next Steps Get Customers - List and search customers Get Customer By ID - Retrieve specific customer Update Customer - Modify customer details Product & Customer Records Guide - Learn more about customer management ## Related Resources Customers API Reference Getting Started Support --- # Creating Transactions Interactive walkthrough for creating transactions and retrieving transaction records Source: https://docs.trykintsugi.com/docs/recipes/creating-transactions ## Overview Transactions represent completed sales in Kintsugi. Each transaction records a sale with customer information, line items, addresses, and tax details. Transactions are used for compliance tracking, nexus determination, and tax filing preparation. Only create transactions for completed sales with confirmed payment. Do not sync pending orders or estimates. ## When to Create Transactions After payment confirmation: When a sale is completed and payment is received Order fulfillment: When an order is shipped or delivered Invoice creation: When generating invoices for completed sales Batch sync: Daily or periodic syncing of completed orders ## Workflow Create a Transaction - Record a completed sale Retrieve Transactions - Search and retrieve transaction records ## Step 1: Create a Transaction Create a transaction using the API Lab below with POST /v1/transactions. Example Request { "external_id": "ORDER-12345", "date": "2024-01-15T10:00:00Z", "currency": "USD", "total_amount": 150.00, "source": "API", "status": "COMMITTED", "type": "SALE", "transaction_items": [ { "external_id": "ITEM-001", "external_product_id": "PROD-001", "product": "Example Product", "quantity": "1.0", "amount": 100.00 } ], "addresses": [ { "type": "SHIP_TO", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } ] } ## Step 2: Retrieve Transactions After creating transactions, retrieve them using GET /v1/transactions. You can: Filter by external_id using the search_query parameter Filter by date range using date__gte and date__lte Filter by status, state, country, and more Paginate through results ## Authentication This endpoint requires two headers: x-api-key: Your API key x-organization-id: Your organization ID Both headers are required for authentication. You can find your API key and organization ID in your Kintsugi dashboard. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create transaction POST /v1/transactions Record a completed sale. The response returns the stored transaction. { "organization_id": "orgn_YourOrgIdHere", "external_id": "YourUniqueOrder123", "date": "2024-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "marketplace": true, "customer": { "organization_id": "orgn_YourOrgIdHere", "external_id": "Cust456", "name": "John Doe" }, "addresses": [ { "type": "SHIP_TO", "country": "US", "state": "CA", "city": "San Francisco", "postal_code": "94107", "street_1": "123 Main St" } ], "transaction_items": [ { "organization_id": "orgn_YourOrgIdHere", "date": "2024-01-15T14:30:00Z", "external_product_id": "SKU-ABC", "product": "Example Widget", "quantity": 2, "amount": 50 } ], "source": "API" } { "organization_id": "orgn_YourOrgIdHere", "external_id": "YourUniqueOrder123", "date": "2024-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "marketplace": true, "customer": { "organization_id": "orgn_YourOrgIdHere", "external_id": "Cust456", "name": "John Doe" }, "addresses": [ { "type": "SHIP_TO", "country": "US", "state": "CA", "city": "San Francisco", "postal_code": "94107", "street_1": "123 Main St" } ], "transaction_items": [ { "organization_id": "orgn_YourOrgIdHere", "date": "2024-01-15T14:30:00Z", "external_product_id": "SKU-ABC", "product": "Example Widget", "quantity": 2, "amount": 50 } ], "source": "API" } Run 2 Get transaction by id GET /v1/transactions/{transaction_id} Run Run the previous step to fill the path. ## Required Fields external_id: Your unique order identifier date: Transaction date in ISO 8601 format type: Transaction type (for example, SALE) currency: Three-letter currency code (for example, USD) customer: The customer associated with the sale addresses: Transaction addresses; the ship-to address determines the tax jurisdiction transaction_items: The line items sold, each with an amount ## Common Use Cases Basic Transaction Create a simple transaction with minimal required fields: { "external_id": "ORDER-001", "date": "2024-01-15T10:00:00Z", "currency": "USD", "total_amount": 100.00, "source": "API", "status": "COMMITTED", "type": "SALE", "transaction_items": [ { "external_id": "ITEM-001", "external_product_id": "PROD-001", "product": "Widget", "quantity": "1.0", "amount": 100.00 } ], "addresses": [ { "type": "SHIP_TO", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } ] } Transaction with Customer Include customer information: { "external_id": "ORDER-002", "date": "2024-01-15T10:00:00Z", "currency": "USD", "total_amount": 200.00, "source": "API", "status": "COMMITTED", "type": "SALE", "customer": { "external_id": "CUST-001", "name": "John Doe", "email": "john@example.com", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" }, "transaction_items": [ { "external_id": "ITEM-001", "external_product_id": "PROD-001", "product": "Product A", "quantity": "2.0", "amount": 200.00 } ], "addresses": [ { "type": "SHIP_TO", "street_1": "123 Main St", "city": "Seattle", "state": "WA", "postal_code": "98101", "country": "US" } ] } ## Response Fields id: Kintsugi's unique transaction identifier external_id: Your transaction identifier date: Transaction date total_amount: Total transaction amount total_tax_amount_calculated: Calculated tax amount status: Transaction status ## Next Steps Get Transactions - List and search transactions Get Transaction By ID - Retrieve specific transaction Update Transaction - Modify transaction details Syncing Transaction Records - Learn more about transaction management ## Related Resources Transactions API Reference Getting Started Support --- # Creating Credit Notes Interactive walkthrough for creating credit notes (refunds) for sale transactions Source: https://docs.trykintsugi.com/docs/recipes/creating-credit-notes ## Overview Credit notes represent refunds, returns, or adjustments to original transactions. They maintain accurate sales records by reducing taxable amounts when refunds occur, ensuring your tax filings reflect net sales (sales minus refunds) rather than gross sales. You must have the Kintsugi transaction ID (not external_id) of the original transaction to create a credit note. Store transaction IDs after creating transactions for future credit note creation. ## When to Create Credit Notes Full refunds: When a customer returns an entire order Partial refunds: When a customer returns specific items Order cancellations: When an order is cancelled after payment Price adjustments: When correcting pricing errors ## Prerequisites Before creating a credit note, you need: The original transaction must exist in Kintsugi The original transaction must have status "COMMITTED" The Kintsugi transaction ID (not the external_id) ## Workflow Find Original Transaction - Retrieve the original transaction to get its Kintsugi ID Create Credit Note - Create a credit note linked to the original transaction Retrieve Credit Notes - Verify the credit note was created ## Step 1: Find Original Transaction If you don't have the Kintsugi transaction ID, find it using: GET /v1/transactions/external/{external_id} - Find by your external ID GET /v1/transactions - Search transactions and find the ID ## Step 2: Create Credit Note Create a credit note using the API Lab below with POST /v1/transactions/{original_transaction_id}/credit_notes. Example Request { "external_id": "CREDIT-001", "date": "2024-01-20T10:00:00Z", "currency": "USD", "total_amount": -100.00, "source": "API", "status": "COMMITTED", "type": "FULL_CREDIT_NOTE", "transaction_items": [ { "external_id": "ITEM-001", "external_product_id": "PROD-001", "product": "Example Product", "quantity": "1.0", "amount": -100.00 } ] } ## Step 3: Retrieve Credit Notes Credit notes appear in transaction queries. Use GET /v1/transactions with: transaction_type: Filter by "FULL_CREDIT_NOTE" or "PARTIAL_CREDIT_NOTE" related_to: Filter by original transaction ID search_query: Search by credit note external_id ## Authentication This endpoint requires two headers: x-api-key: Your API key x-organization-id: Your organization ID Both headers are required for authentication. You can find your API key and organization ID in your Kintsugi dashboard. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create the original transaction POST /v1/transactions { "organization_id": "orgn_YourOrgIdHere", "external_id": "YourUniqueOrder123", "date": "2024-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "marketplace": true, "customer": { "organization_id": "orgn_YourOrgIdHere", "external_id": "Cust456", "name": "John Doe" }, "addresses": [ { "type": "SHIP_TO", "country": "US", "state": "CA", "city": "San Francisco", "postal_code": "94107", "street_1": "123 Main St" } ], "transaction_items": [ { "organization_id": "orgn_YourOrgIdHere", "date": "2024-01-15T14:30:00Z", "external_product_id": "SKU-ABC", "product": "Example Widget", "quantity": 2, "amount": 50 } ], "source": "API" } { "organization_id": "orgn_YourOrgIdHere", "external_id": "YourUniqueOrder123", "date": "2024-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "marketplace": true, "customer": { "organization_id": "orgn_YourOrgIdHere", "external_id": "Cust456", "name": "John Doe" }, "addresses": [ { "type": "SHIP_TO", "country": "US", "state": "CA", "city": "San Francisco", "postal_code": "94107", "street_1": "123 Main St" } ], "transaction_items": [ { "organization_id": "orgn_YourOrgIdHere", "date": "2024-01-15T14:30:00Z", "external_product_id": "SKU-ABC", "product": "Example Widget", "quantity": 2, "amount": 50 } ], "source": "API" } Run 2 Issue a credit note POST /v1/transactions/{original_transaction_id}/credit_notes { "external_id": "CN-12345", "date": "2024-10-27T14:30:00Z", "status": "PENDING", ## Try It Out "description": "Refund for damaged product", "total_amount": 50, "external_customer_id": "CUST-456", "currency": "USD", "transaction_items": [ { "external_id": "ITEM-1", "date": "2024-10-27T14:30:00Z", "external_product_id": "PROD-ABC", "quantity": 1, "amount": 50 } ] } { "external_id": "CN-12345", "date": "2024-10-27T14:30:00Z", "status": "PENDING", "description": "Refund for damaged product", "total_amount": 50, "external_customer_id": "CUST-456", "currency": "USD", "transaction_items": [ { "external_id": "ITEM-1", "date": "2024-10-27T14:30:00Z", "external_product_id": "PROD-ABC", "quantity": 1, "amount": 50 } ] } Run Run the previous step to fill the path. ## Required Fields original_transaction_id (path): The ID of the original transaction being credited external_id: Your unique credit note identifier date: Credit note date in ISO 8601 format status: Credit note status (for example, PENDING) total_amount: The refund amount currency: Three-letter currency code (for example, USD) transaction_items: The line items being credited, each with an amount ## Common Use Cases Full Refund Create a credit note for a full refund: { "external_id": "REFUND-001", "date": "2024-01-20T10:00:00Z", "currency": "USD", "total_amount": -150.00, "source": "API", "status": "COMMITTED", "type": "FULL_CREDIT_NOTE", "transaction_items": [ { "external_id": "ITEM-001", "external_product_id": "PROD-001", "product": "Product A", "quantity": "1.0", "amount": -100.00 }, { "external_id": "ITEM-002", "external_product_id": "PROD-002", "product": "Product B", "quantity": "1.0", "amount": -50.00 } ] } Partial Refund Create a credit note for a partial refund: { "external_id": "REFUND-002", "date": "2024-01-20T10:00:00Z", "currency": "USD", "total_amount": -50.00, "source": "API", "status": "COMMITTED", "type": "PARTIAL_CREDIT_NOTE", "transaction_items": [ { "external_id": "ITEM-001", "external_product_id": "PROD-001", "product": "Product A", "quantity": "1.0", "amount": -50.00 } ] } ## Response Fields id: Kintsugi's unique credit note identifier external_id: Your credit note identifier related_to: The original transaction this credit note applies to date: Credit note date total_amount: Refund amount type: Credit note type (FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE) status: Transaction status ## Next Steps Get Transactions - List and search credit notes Update Credit Note - Modify credit note details Handling Refund Transactions - Learn more about credit notes ## Related Resources Create Credit Note API Reference Getting Started Support --- # Managing Nexus Interactive walkthrough for creating physical nexus, registrations, and retrieving nexus information Source: https://docs.trykintsugi.com/docs/recipes/managing-nexus ## Overview Nexus determines where your business has a tax obligation. Physical nexus represents business locations (offices, warehouses, employees), while registrations represent jurisdictions where you're registered to collect and remit sales tax. This API Lab covers managing both physical nexus and registrations. ## Understanding Nexus Types Physical Nexus: Business locations that create tax obligations (offices, warehouses, employees) Registrations: Jurisdictions where you're registered to collect and remit tax ## Workflow Create Physical Nexus - Record a physical business location Create Registration - Register in a jurisdiction Retrieve Nexus - View all physical nexus records Retrieve Registrations - View all registrations ## Step 1: Create Physical Nexus Create a physical nexus record using the API Lab below with POST /v1/nexus/physical_nexus. Example Request { "country_code": "US", "state_code": "CA", "start_date": "2024-01-01", "category": "PHYSICAL_BUSINESS_LOCATION" } ## Step 2: Create Registration Create a registration using POST /v1/registrations. This represents a jurisdiction where you're registered to collect tax. Example Request { "country_code": "US", "state_code": "CA", "state_name": "California", "registration_date": "2024-01-01", "filing_frequency": "MONTHLY" } ## Step 3: Retrieve Physical Nexus Retrieve physical nexus records using GET /v1/nexus/physical_nexus. You can filter by: country_code: Filter by country state_code: Filter by state Pagination: Use page and size parameters ## Step 4: Retrieve Registrations Retrieve registrations using GET /v1/registrations. You can filter by: country_code__in: Filter by countries state_code: Filter by state status__in: Filter by registration status Pagination: Use page and size parameters ## Authentication These endpoints require two headers: x-api-key: Your API key x-organization-id: Your organization ID Both headers are required for authentication. You can find your API key and organization ID in your Kintsugi dashboard. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create physical nexus POST /v1/nexus/physical_nexus { "country_code": "US", "state_code": "CA", "start_date": "2024-01-01", "end_date": "2025-01-01", "category": "PHYSICAL_BUSINESS_LOCATION", "external_id": "ext_ABC123", "source": "USER", "street_1": "123 Main Street", "street_2": "Suite 100", "city": "San Francisco", "postal_code": "94102" } { "country_code": "US", "state_code": "CA", "start_date": "2024-01-01", "end_date": "2025-01-01", "category": "PHYSICAL_BUSINESS_LOCATION", "external_id": "ext_ABC123", "source": "USER", "street_1": "123 Main Street", "street_2": "Suite 100", "city": "San Francisco", "postal_code": "94102" } Run 2 Create registration POST /v1/registrations { "registration_date": "2025-02-01", "registration_email": "example@domain.com", "country_code": "US", "state_code": "TX", "state_name": "Texas", "filing_frequency": "MONTHLY", "auto_registered": true, "amount_fees": 100, "comment": "Registering for monthly sales tax filings", "initial_sync": false } { "registration_date": "2025-02-01", "registration_email": "example@domain.com", "country_code": "US", "state_code": "TX", "state_name": "Texas", "filing_frequency": "MONTHLY", "auto_registered": true, "amount_fees": 100, "comment": "Registering for monthly sales tax filings", "initial_sync": false } Run 3 Get nexus for org GET /v1/nexus Read back the nexus footprint for your organization. Run ## Required Fields Physical Nexus country_code: Country code (for example, US) state_code: State code (for example, CA) start_date: Date the nexus obligation began category: Nexus category Registration country_code: Country code (for example, US) state_code: State code (for example, TX) registration_date: Date the registration became effective filing_frequency: How often you file returns (for example, MONTHLY) ## Common Use Cases Physical Business Location Create nexus for a physical office or warehouse: { "country_code": "US", "state_code": "CA", "start_date": "2024-01-01", "category": "PHYSICAL_BUSINESS_LOCATION", "external_id": "LOCATION-001" } Employee Location Create nexus based on employee location: { "country_code": "US", "state_code": "NY", "start_date": "2024-01-15", "category": "EMPLOYEE_LOCATION", "external_id": "EMPLOYEE-NY-001" } Registration Create a registration for a jurisdiction: { "country_code": "US", "state_code": "CA", "state_name": "California", "registration_date": "2024-01-01", "filing_frequency": "MONTHLY", "sales_tax_id": "123456789" } ## Response Fields Create physical nexus external_id: Your nexus identifier country_code: Country code state_code: State code start_date: Nexus start date end_date: Nexus end date (if applicable) category: Nexus category Create registration id: Unique registration identifier country_code: Country code state_code: State code status: Registration status filing_frequency: How often you file returns registration_date: Date the registration was recorded ## Next Steps Get Physical Nexus - List physical nexus Get Registrations - List registrations Update Physical Nexus - Modify nexus details Update Registration - Modify registration details ## Related Resources Nexus API Reference Registrations API Reference Getting Started Support --- # Getting Started with Kintsugi (2026-10-06) Connect your sales data, configure your business, and get Kintsugi calculating, registering, and filing sales tax on your behalf Source: https://docs.trykintsugi.com/docs/2026-10-06/getting-started Kintsugi automates sales tax end to end. It watches where your sales create an obligation, prices the right rate at checkout, registers you in the jurisdictions that require it, and files and remits on schedule. Setup is five steps, and this page covers all of them, with the Tenanted API endpoint for each one you can also do in code. What to expect: the first three steps are yours to complete and take an afternoon at most. Registrations move at the speed of each state's tax authority, so plan for those to land over days rather than minutes. Quick Setup The five steps, in order, from connecting data to approving your first filing. Plan an Integration Choose how you will integrate before you write code. API Keys and Authentication Create a key, then make your first authenticated request. API Reference Every Tenanted endpoint, with real request and response shapes from the spec. ## Quick Setup Five steps, in order. Each one unlocks the next: Kintsugi cannot price a product it has not classified, and cannot file a return in a jurisdiction where you are not registered. Connect Your Data Kintsugi works from your sales history. Nexus, rates, and returns are all derived from the transactions you send, so connecting a data source comes first. Open Data Sources in the app and click Connect, then choose the route that matches your stack. Direct Integration Dozens of prebuilt connectors cover shopping carts, billing systems, ERPs, and accounting platforms. Pick your platform, authorize it once, and Kintsugi keeps transactions in sync from then on. List connections shows the connections an organization has. Custom Integration Build against the REST API. Start with Planning an Integration to choose your approach, then Syncing Transaction Records for the payload shape, and use the API Lab to run each workflow before you build it. The official SDKs for Python, TypeScript, Java, PHP, and Ruby use the v1 API. They do not cover the Tenanted API yet, so call it over HTTP. CSV Upload Download Kintsugi's template, fill it in, and upload it. File Upload documents every column the importer reads, and uploaded transactions behave exactly like ones created through the API. Import Historical Data Send transactions covering the previous full calendar year through today. Kintsugi determines nexus by looking back across that window, so without it we cannot tell you when you crossed a threshold or when your filing obligation began. CSV is usually the fastest way to backfill: see File Upload for the template and column reference. Coming from another provider? Migrating from Avalara or TaxJar covers exporting your history and cutting over without breaking a filing period. ## Quick Setup Skipping history does not stop Kintsugi from tracking new sales, but it does mean nexus start dates and past exposure have to be set from your own records. Import the history if you have it. Configure Your Business Kintsugi needs three things about your company: where you have people and property, who you are on a tax return, and how you pay. Physical Presence Economic nexus comes out of your transaction data automatically. Physical nexus does not, because no transaction records it. Tell Kintsugi where you have: Offices, stores, or warehouses Employees or contractors, including remote staff working from home Inventory held for sale, including stock in a third-party fulfillment center you have never visited Traveling sales representatives If you are unsure, enter what you know and Kintsugi flags the jurisdictions worth a second look. US Sales Tax for Developers explains how each activity creates an obligation, and physical presence can also be managed programmatically through Record a physical presence. Physical nexus carries no grace threshold. Unlike economic nexus, it applies from your first taxable sale into that state, so record presence as soon as it exists. Organization Details These details appear verbatim on your registrations and returns, so match them to your incorporation documents rather than your brand name: Legal business name and address Tax ID numbers Entity type and industry Contact for jurisdiction correspondence Reading or updating them from your own systems: Get organization details and Update organization details. Banking Information Kintsugi debits the tax it remits on your behalf, so bank details are required before your first filing rather than before setup: Bank account for tax payments ACH authorization Payment preferences ## Quick Setup Banking details are encrypted at rest and used only to remit tax on your behalf. Classify Products and Validate Addresses Two inputs decide every rate Kintsugi calculates: what you sold, and where it went. Product Classification Taxability is decided per product, not per order. A t-shirt, a downloadable report, and a SaaS subscription are treated differently in the same state, so each product needs a category before Kintsugi can price it. Approving a product means confirming the category assigned to it. Kintsugi Intelligence Let Kintsugi Intelligence classify the catalog, then spot-check the results. The best starting point for a large catalog. Bulk Approval Use bulk approve to accept the assigned categories across the catalog in one action. Fastest when your products are uniform. Through the API: Approve partially approved products in bulk. Manual Review Set the category product by product. Worth the time for bundles, digital goods, and anything with unusual treatment. Product Categories explains how categories and subcategories map to taxability, and List the product category catalog returns the full catalog of values. Creating products through the API instead? See Create a product. Address Validation A rate is a function of an address, not a state. A postal code resolves to a county, city, and any special districts on top; a state on its own does not, and the gap between the two is often several percent. Open Tasks to see the transactions Kintsugi could not resolve Use Kintsugi Intelligence to fill in missing components Review anything still flagged, since these are the rows most likely to be wrong on a return ## Quick Setup Validate addresses in your own checkout before you calculate tax, and you avoid the correction later. See Validate and enrich an address for the endpoint. Review Nexus and Exemptions With data and configuration in place, Kintsugi can tell you where you owe and who is exempt. Nexus Review Open Nexus to see where you have crossed a threshold, where you are approaching one, and where you have no obligation yet. The exposure map on your dashboard is the same picture, by geography. Kintsugi monitors nexus continuously and alerts you when a new obligation appears, so this is a review rather than something to recheck by hand. Reading it programmatically: List nexus determinations. Exemption Management If you sell to resellers, nonprofits, or government buyers, record the exemption before you collect tax you will have to refund: Configure customer exemptions in the Exemptions section Set product-level exemptions where a category is treated differently Upload and manage exemption certificates so they are on file for an audit Through the API: Create an exemption and Upload an exemption certificate. Register, File, and Remit Nexus tells you where you owe. A registration is what makes filing possible, so this is the step that turns monitoring into compliance. Register in New Jurisdictions Click Register on the Nexus page for each jurisdiction where you have nexus. Kintsugi handles the application; processing time is set by the state, not by us. Import Existing Registrations Already registered somewhere? Import the registration with its effective date and filing frequency so Kintsugi picks up returns from the right period rather than the day you signed up. See Create a registration. File and Remit ## Quick Setup Review your returns on the Filings page and click Approve to file and remit in each jurisdiction. List filings exposes the same records to your own systems, and Approve a filing approves one. Once a jurisdiction is registered and its first filing is approved, Kintsugi files and remits there on schedule without further action from you. ## Next Steps Setup is done. Where you go next depends on whether you are operating Kintsugi or building on it. Create an API Key Generate a key and store it safely. Make Your First Request Authenticate with your key in the Api-Key header. Plan an Integration Choose your approach, then sequence the build. API Lab Run each workflow interactively before you code it. US Sales Tax for Developers Nexus, taxability, exemptions, and sourcing explained. Kintsugi MCP Point your AI coding assistant at the v1 API and docs. Day to day, the records you will read most are customers, transactions, and registrations. ## Need Help? Common Questions Setup Issues Integration will not connect? Recheck the credentials and permissions on the connection in Data Sources, then see Error Handling for what the response is telling you. Data not syncing? Confirm your API key is active and that every request carries it in the Api-Key header. See Making an Authenticated Request. Tax calculations look wrong? Check the product's classification first and the destination address second. Those two inputs account for most surprises. See Product Categories. Nexus dates look wrong? Usually a gap in historical data. See Syncing Transaction Records. Account Management Change your business information: Settings > Organization. These values flow to registrations and returns, so update them before your next filing. Add team members: the Users section of your dashboard. Update billing: the Help Center covers subscriptions, invoices, and payment methods. Technical Support Endpoint details: the API Reference is generated from the Tenanted API spec. Client libraries: the SDKs for Python, TypeScript, Java, PHP, and Ruby use the v1 API and do not cover the Tenanted API yet. Error responses: Error Handling covers status codes, error codes, and retries. Building with an AI assistant: Kintsugi MCP works with the v1 API. Get Support Email Support Reach our support team at success@trykintsugi.com. Phone Support Call +1 (415) 840-8847. Live Chat Chat with us in real time. Help Center Product, billing, and filing guides, outside the developer docs. FAQ Answers to the questions we hear most. Community Coming soon Connect with other Kintsugi users. --- # Creating and Managing API Keys (2026-10-06) Create an API key in the Kintsugi app, store it safely, and rotate or revoke it later Source: https://docs.trykintsugi.com/docs/2026-10-06/getting-started/creating-and-managing-api-keys Every Tenanted API request to a data endpoint carries an API key in the Api-Key header. This page covers creating a key in the app, the one moment you can copy it, and how to manage keys after that, in the app or through the API Keys endpoints. Create Your First Key Four clicks in the Configuration page. Store It Safely The key is shown once and never again. Make an Authenticated Request Send your key and confirm it works. API Reference Every endpoint your key can reach. ## Before You Start You need an account on the Kintsugi platform and access to an organization. API keys need a paid plan that includes them. If the API Keys tab asks you to upgrade, the organization you are signed in to does not include them yet, so check which organization you are in before you start. A key created in the app is scoped to one organization and acts on that organization, so a request made with it needs no organization header. You can hold several keys at once, which is what makes rotation possible without downtime. ## Create an API Key Open the API Keys Tab Sign in to the Kintsugi platform. If you do not have an account yet, sign up first. Select Configuration in the left sidebar, below Tools. Configuration sits at the bottom of the sidebar, above your name and the organization switcher. Configuration opens on a row of tabs. Select API Keys. Configuration tabs: API Keys sits between Users and Exemptions. The tab lists every key belonging to the organization you are signed in to, with a search box, a link back to this documentation, and a New button. A new organization has none yet. The API Keys tab before any key exists. Create a New API Key Click New. The New Organization API Key dialog opens, named for the scope the key will have. Choose when the key should expire: Never, One Month, Six Month, or One Year. Expiry is the only decision the dialog asks you to make. Pick the shortest window that covers the work. An expiring key limits how long a leaked one is useful, and the expiry date is the reminder to rotate. One Month suits local development and spikes, One Year suits a production integration you will rotate on schedule, and Never is worth choosing only when something other than the calendar will retire the key. Confirm to generate the key. Copy and Secure Your API Key This is the only time the key is visible. Copy it before you close the dialog. There is no way to reveal it again, so a key you did not copy has to be deleted and replaced. Click the copy icon, or Manually copy API key to select the full value yourself. Copy the key here, or lose it. Paste it straight into wherever your application reads secrets from, before you do anything else. Click Done. Three habits worth keeping from the start: ## Create an API Key Read the key from the environment, never from source. A key in a commit is a key in your history, and rewriting history is a worse afternoon than rotating a key. Use a separate key per application and environment. Keys are independent, so one can be revoked without taking the others down with it. Share through a password manager, not chat or email. Viewing and Managing Your API Keys The API Keys tab lists each key with its truncated value under KEY, plus its CREATED and EXPIRES dates. Only the truncated form is ever shown again. Use the search box to find a key, and the three-dot menu (⋮) at the end of its row to delete it. An existing key, and the delete action on its row menu. Deleting a key takes effect immediately and cannot be undone. Anything still using it starts getting 401 unauthorized on the next call, so put the replacement in place first. See Error Handling for what an authentication failure looks like. ## Managing Keys Through the API The Tenanted API exposes the same lifecycle as four endpoints. They manage credentials, so they do not accept an organization API key: they take the session token of a signed-in Owner or Admin, sent as Authorization: Bearer , with Organization-Id naming the organization whose keys you are managing. An organization API key gets 401 unauthorized, and a request that sends both an Api-Key and a bearer token gets 400 multiple_credentials. | Endpoint | What it does | | --- | --- | | GET /api-keys | Lists the organization's keys. active=false lists archived keys instead of current ones. Pages forward with limit (1 to 100, default 50) and cursor. | | POST /api-keys | Creates a key and returns its secret token, once. | | PATCH /api-keys/{api_key_id} | Changes a key's expiresAt, or removes the expiry with null. | | DELETE /api-keys/{api_key_id} | Revokes a key. | Creating a key takes one optional field. expiresAt is an RFC 3339 UTC timestamp ending in Z, and it has to be in the future; leave it out for a key that does not expire. POST https://api.trykintsugi.com/api-keys -H "Authorization: Bearer " -H "Organization-Id: orgn_12345" -H "Api-Version: 2026-07-21" -H "Content-Type: application/json" { "expiresAt": "2027-07-21T15:30:00Z" } A 201 Created returns the key's id and its token: { "id": "3f6c2b1e-8a4d-4c2e-9b1f-2d7e5a6c9f10", "token": "tok_2mNpQr7Ls8f3k" } The token is returned here and never again. Listing keys returns their metadata ( id, scope, organizationId, createdAt, expiresAt), never the secret, so store the token before you do anything else. A few rules worth knowing: ## Managing Keys Through the API Updating sends expiresAt with a new future timestamp, or null to remove the expiry. An empty body returns 400 invalid_request, since it asks for no change. A successful update returns 204 No Content. Revoking returns 204 No Content. A key you cannot revoke, including one that does not exist, returns 404 not_found. A signed-in user without the Owner or Admin role gets 403 forbidden. ## Rotating a Key Because an organization can hold several keys at once, rotation needs no downtime and no maintenance window: Create the replacement Generate a new key alongside the one you are retiring, in the app or with Create an API key. Deploy it Update the secret your application reads and roll it out. Confirm the new key is live Make a request and check it succeeds. Making an Authenticated Request is the quickest check. Delete the old key Only once nothing is using it. Deleting first is what turns a rotation into an outage. Set expiry when you create the key and rotation stops being something you have to remember. The EXPIRES column is your schedule, and expiresAt on List API keys is the same date for your own tooling. ## Next Steps Make an Authenticated Request Send Api-Key, and learn when to add an organization selector. Plan an Integration Choose how you will integrate before you write code. SDKs Python, TypeScript, Java, PHP, and Ruby clients for the v1 API. API Lab Run each workflow interactively before you build it. Error Handling Status codes, error codes, and what a rejected key returns. Kintsugi MCP Give your AI coding assistant the v1 API and docs. ## Need Help? Common Issues Creating a Key API Keys tab asks you to upgrade? API keys need a paid plan that includes them. Check the organization switcher in the lower left to confirm which organization you are in. Permission denied? Through the API, managing keys takes the Owner or Admin role. Ask an Owner or Admin on your organization, in the Users tab. Key not generating? Reload the Configuration page and try again. If it persists, contact support. Using a Key 401 unauthorized? The key is wrong, expired, or deleted. Check the EXPIRES column, and check the header name is Api-Key. 404 not_found on every request? If you send Organization-Id, it has to name the organization the key was created in. Remove it, or correct it. 401 unauthorized on Users or API Keys endpoints? Those endpoints do not accept an organization API key. Send a signed-in user's session token instead. See Making an Authenticated Request. Reading the response: Error Handling covers each status code and error code. Lost or Leaked Keys Lost the key? It cannot be recovered. Delete it and create another. Key leaked? Delete it immediately, then create and deploy a replacement. Deleting is instant. Committed a key to git? Delete the key first, then clean the history. Revoking is what actually stops it being used. Which key is which? Match the truncated value in the KEY column against the start of the key your application holds. Get Support Email Support Reach our support team at success@trykintsugi.com. Phone Support Call +1 (415) 840-8847. Live Chat Chat with us in real time. Help Center Product, billing, and filing guides, outside the developer docs. API Reference Every Tenanted endpoint, generated from the spec. Developer Community Coming soon ## Need Help? Connect with other developers building on Kintsugi. --- # Authenticating Your Requests (2026-10-06) Send your API key on every request, choose an organization when your key reaches more than one, verify it works, and read what a rejected call is telling you Source: https://docs.trykintsugi.com/docs/2026-10-06/getting-started/authentication The Tenanted API authenticates a request with one header: Api-Key carries the key you created in the app. A key created in the app belongs to one organization, so it already knows which organization you are acting for. There is no /v1 prefix in the path, and an optional Api-Version header pins the release. The Headers What each one is, and when you need it. Your First Request One call that verifies your key without changing anything. When a Request Is Rejected What 401, 403, 404, and 405 are each telling you. API Reference Every Tenanted endpoint, with the credential each one accepts. ## Before You Start You need one value: An API key. Create one in the app: Creating and Managing API Keys. You do not need an organization ID to get started. A key created in the app is issued against one organization, and a request that names no organization runs against that one. ## The Headers Every request goes to https://api.trykintsugi.com, with no version prefix in the path: | Header | What it is | When to send it | | --- | --- | --- | | Api-Key | The key you created in the app. Identifies the caller. | On every request to an endpoint that takes an API key. | | Api-Version | The release to run against, as YYYY-MM-DD. | Optional. Without it, the request runs against 2026-07-21. | | Organization-Id | The organization the request acts on. | Optional. Only needed when your credential reaches more than one organization. | | Connection-Id | A connection ID. Resolves to that connection's organization. | Optional selector, an alternative to Organization-Id. | | Entity-Id | A platform entity ID. Resolves to a connection's organization. | Optional selector. Add Entity-Source to disambiguate it. | The default release never moves. A request without Api-Version runs against 2026-07-21, the launch release, today and after newer releases ship, so leaving the header out can never change an integration underneath you. Sending it anyway makes the release you built against explicit in your own code. HTTP header names are case-insensitive, so Api-Key and api-key are the same header. The API Reference and the examples here use Api-Key; either is fine, and it is worth picking one and staying with it. Choosing an Organization If you send a selector, it has to name an organization your key can reach. Naming one it cannot reach returns 404 not_found, the same response as an organization that does not exist, so a key can never be used to probe which organizations exist. When a credential reaches more than one organization, the selector is how you pick one: A write with no selector returns 400 missing_target_selector, because a create cannot mean "all of them". ## The Headers Selectors that point at different organizations return 400 conflicting_target_selectors. An Entity-Id that matches more than one connection returns 409 entity_resolution_ambiguous. Add Entity-Source or Connection-Id to settle it. List organizations returns every organization your credential can access, which is where to read the ID from when you need one. Your API key belongs on your server, never in a browser or a mobile app. Anything shipped to a client is readable by whoever holds it, and a leaked key can act on your whole organization. Call Kintsugi from your backend and let your own frontend talk to that. Endpoints That Take a Session Token A small set of endpoints manage people and credentials rather than data, and they do not accept an organization API key: Users, such as List organization users and Invite a user to an organization, accept only a signed-in user's session token, sent as Authorization: Bearer . An API key is rejected. API Keys, such as Create an API key, take a session token from an Owner or Admin. An organization API key gets 401 unauthorized, exactly as if no credential had been sent, and sending both an Api-Key and a bearer token returns 400 multiple_credentials. A few public endpoints take no credential at all. The API Reference shows the credential each endpoint accepts. ## Your First Request Start with a read. GET /products/categories returns Kintsugi's product category catalog. It takes no parameters and no selector, and the catalog is the same for every caller, which makes it a clean way to prove your key works without creating anything: curl https://api.trykintsugi.com/products/categories \ -H "Api-Key: $KINTSUGI_API_KEY" \ -H "Api-Version: 2026-07-21" A 200 with a JSON body means your key is good and you are ready to build. Read the key from the environment, as above, rather than pasting it into the command. That keeps it out of your shell history as well as out of your source. See List the product category catalog for the response shape. Once that works, every other data endpoint takes the same Api-Key header. The API Reference carries a ready-made request for each one, and the API Lab runs whole workflows interactively so you can see the sequence before you write it. ## When a Request Is Rejected Every error comes back in the same envelope, and the code tells you where to look: { "code": "unauthorized", "message": "Invalid API key.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } | Status and code | What went wrong | Where to look | | --- | --- | --- | | 401 unauthorized | No credential was sent, or the key did not validate. | Check the header is named Api-Key, then the EXPIRES column on the API Keys tab. On Users and API Keys endpoints, this is also what an API key gets: send a session token instead. | | 403 forbidden | The credential is valid but not permitted to perform this operation. | On Users and API Keys endpoints, the signed-in user needs the Owner or Admin role. | | 404 not_found | The resource does not exist, or belongs to an organization your credential cannot reach. | Check the ID, and check any Organization-Id, Connection-Id, or Entity-Id you sent. | | 405 method_not_allowed | Your credential was fine; the method was wrong. | Check the method in the reference. POST /tax-estimations, for example, rejects a GET. The response carries an Allow header naming the methods the path accepts. | Branch on code, not on message: the message is written for people and can change. Quote the requestId when you contact support. Error Handling covers the full set of status codes and error codes, field-level validation errors, and retry behavior. ## Using an SDK Instead The official SDKs and the Kintsugi MCP server use the v1 API, with its x-api-key and x-organization-id headers and /v1 paths. They do not cover the Tenanted API yet, so call the Tenanted API over HTTP as shown on this page. SDK Quick Start Install a client for the v1 API. All SDKs Python, TypeScript, Java, PHP, and Ruby, for the v1 API. Kintsugi MCP Point your AI coding assistant at the v1 API and docs. ## Next Steps Plan an Integration Choose how you will integrate before you write code. Calculate Tax The endpoint most integrations reach for first. Sync Transactions Record completed sales, which is what nexus is derived from. API Lab Run each workflow interactively before you build it. Error Handling Status codes, error codes, and retries. Rotate Your Key Swap a key with no downtime. --- # US Sales Tax for Developers (2026-10-06) The concepts behind every tax calculation: nexus, product taxability, exemptions, sourcing, and marketplace facilitator rules Source: https://docs.trykintsugi.com/docs/2026-10-06/guides/sales-tax-for-developers Building e-commerce platforms, SaaS applications, and marketplaces means working inside one of the most fragmented regulatory systems in software: US sales tax. There is no federal sales tax and no single rulebook. Instead there are 45 states and the District of Columbia that impose one, local jurisdictions in Alaska that impose their own, and more than 11,000 taxing jurisdictions in total, each with its own rates, thresholds, and definitions of what counts as taxable. This guide covers the concepts that decide the number on the invoice. Get these right and the API calls are straightforward. For implementation details, see the Tax Estimate guide and the API Reference. ## The Four-Factor Taxability Framework Sales tax is not a yes or no decision. Every transaction runs the same four checks, in this order, and the first "no" ends it and returns zero tax. 1 Nexus and registration Do you owe anything in this state at all? Tax is only due where an active registration covers the destination. Nexus is the obligation; the registration is the permit that lets you collect against it. See nexus types below. NO → No tax. The estimate comes back with hasActiveRegistration: false and every amount at zero. The estimate reports the registration, not nexus. Nexus lives on nexus determinations as economicNexusMet and physicalNexusMet. Set simulateActiveRegistration to true to price the sale as if you were registered. 2 Product taxability Is this thing taxable here? Driven by the item's product category. Groceries, clothing and SaaS all swing state by state. NO → Exempt product. The line comes back with exempt: true and an exemptReason saying why. Each entry in the line's taxItems reports the outcome of the rule lookup behind that tax. 3 Customer exemption Is this buyer exempt? Resellers, government agencies, nonprofits and educational institutions, backed by a certificate on file. YES → No tax. The line comes back with exempt: true and an exemptReason, and the certificate is what defends it in an audit. When customer.externalId matches a customer Kintsugi already holds, that customer's exemptions and tax registrations are applied automatically. Only an exemption with status ACTIVE is applied. For a one-off that belongs to no customer record, set exempt: true on the line instead. 4 Sourcing Whose rate applies? ## The Four-Factor Taxability Framework Destination states use the buyer's delivery address; a handful of origin states use the seller's location for sales inside their own borders. This decides which jurisdictions appear in taxItems, never whether tax is due. All four pass, so tax is due Each line's taxItems lists the tax applied per jurisdiction, and its taxRate is the combined rate. At checkout Collect the tax Charged to the buyer. The money is not yours to hold. On the filing date Remit and file On the frequency the state assigns: monthly, quarterly or annually. Order matters, and check 2 needs data from you. Each estimate line names either an externalProductId you have already created or a productCategory and productSubcategory pair from the catalog. A pair that does not match the catalog returns 400, and a product that has not been classified yet is priced under the product code UNKNOWN_UNKNOWN. 1. Nexus - The Business Connection Does your business have a connection to this state? Without nexus you have no obligation to collect in that jurisdiction. Nexus comes in two forms: Physical nexus: offices, warehouses, employees, inventory Economic nexus: sales volume or transaction count thresholds Remote employees create physical nexus in the state where they work, even from a home office. So does inventory sitting in a third-party fulfillment center you have never visited. 2. Product Taxability - What's Actually Taxable Is this product or service taxable in this state? Taxability is set by the item's product category, and it varies sharply by state: Physical Goods Almost always taxable: electronics, furniture, general merchandise Often exempt: groceries, prescription drugs, medical devices ## The Four-Factor Taxability Framework State-specific: clothing, which is exempt in Pennsylvania, taxable in California, and exempt below a price cap in New York and Massachusetts Digital Products Taxable: Colorado, Connecticut, Hawaii, Texas, Washington Generally exempt: California, Florida, Nevada Digital goods and software are separate questions in many states, so treat them separately SaaS Taxable: New York, Texas, Pennsylvania, Washington, Massachusetts, Ohio Generally exempt: California, Florida, Virginia Some states tax business use and exempt personal use, or the reverse Services Generally exempt: most states, historically Broadly taxable: Hawaii, New Mexico, South Dakota, West Virginia Selective: repair, installation, and some professional services, state by state Taxability rules change every legislative session, and digital products and services are where they change fastest. Kintsugi maintains the current rules, so classify the product correctly and let the platform resolve the rate. 3. Customer Exemptions - Who Gets Special Treatment Does this buyer qualify for an exemption? Commonly exempt buyers: Businesses purchasing for resale Government agencies Nonprofit organizations Educational institutions Exemptions apply to an estimate in two ways. When customer.externalId matches a customer Kintsugi already holds, that customer's exemptions and tax registrations are applied automatically. For a one-off that belongs to no customer record, set exempt: true on the line. Only an exemption with status ACTIVE is applied by tax calculation. An exemption is only as good as its certificate. Selling tax-free without valid documentation on file leaves you liable for the tax an auditor says you should have collected, plus penalties and interest. 4. Sourcing - Where to Apply the Rate ## The Four-Factor Taxability Framework Which address determines the rate? Destination-based: the buyer's delivery address, which covers nearly every state and every remote sale Origin-based: the seller's location, which a handful of states use for sales inside their own borders Sourcing decides which rate applies. It never decides whether tax is due. See Sourcing Rules below. ## Nexus Types: Physical vs Economic Before 2018, a state could only tax sellers with a physical presence inside it. South Dakota v. Wayfair removed that limit, and every state with a sales tax now also asserts economic nexus. The two are independent, and one is enough. Type A Physical nexus Something of yours is in the state. Any one of these triggers it Offices, stores and warehouses Employees and contractors, including remote staff Inventory storage, including 3PL Trade shows and events Obligation starts Immediately Register before the first taxable sale. There is no grace threshold. Type B Economic nexus You sold enough into the state. Usually either one triggers it Sales volume Commonly $100,000, measured over a rolling year or a calendar year. Transaction count Often 200 sales, though many states have dropped it. Obligation starts On the effective date The state sets it once you cross. Register, then collect from that date. Thresholds, measurement windows and combination rules all vary. New York needs both $500,000 and more than 100 sales; California and Texas look at $500,000 in sales alone. Kintsugi tracks the live values per state, so treat these numbers as shape, not law. Nexus and registration are different things. Nexus is the obligation; a registration is the permit that lets you collect against it. Kintsugi calculates tax where you hold an active registration, and the estimate response reports hasActiveRegistration so you can tell a zero-tax sale from an unregistered one. Set simulateActiveRegistration to true to see what the sale would be taxed at if you were registered. Nexus itself lives on nexus determinations, which report economicNexusMet and physicalNexusMet per jurisdiction. Monitor Sales by State ## Nexus Types: Physical vs Economic Track revenue and transaction counts per state against that state's own threshold, window, and combination rule. Set Up Threshold Alerts Watch for states you are approaching, not just states you have crossed. Registration takes time. Register Before Collecting Collecting sales tax without a permit is unlawful in every state that levies it. The money is not yours to hold. Collect From the Effective Date Start collecting on the date the permit takes effect, which is not always the date you applied or the date it arrived. ## Sourcing Rules: Origin vs Destination You have nexus and a taxable product. One question remains: whose rate applies? Remote sales are always destination-sourced. Origin sourcing is a rule for intrastate sales, where the seller has a location in the same state as the buyer. If you are a remote seller with economic nexus and no presence in the state, use the ship-to address regardless of that state's intrastate rule. Destination-Based Sourcing The rate follows the buyer's delivery address How it works: A Los Angeles merchant charges the San Diego rate on a San Diego delivery Every delivery address is potentially a different rate With more than 11,000 jurisdictions in play, the rate is an address lookup, not a state lookup Kintsugi sources an estimate to the SHIP_TO address when one is supplied, otherwise to BILL_TO. Sending a complete, validated ship-to address is the highest-leverage thing you can do for rate accuracy. Origin-Based Sourcing The rate follows the seller's location, for intrastate sales only States: Arizona, Illinois, Mississippi, Missouri, Ohio, Pennsylvania, Tennessee, Texas, Utah, Virginia. California is a hybrid, below. How it works: An Austin merchant with a Texas location charges the Austin rate to Texas customers Same rate whether the order ships to Dallas, Houston, or rural West Texas Cheaper to compute, and it concentrates local revenue where businesses sit California's Hybrid Sourcing Two sourcing rules on one order State, county, and city taxes: origin-based District taxes: destination-based A single California order can therefore draw on both the seller's and the buyer's address, which is why California is the state most worth testing against real addresses rather than assumptions. ## Marketplace Facilitators Every state with a sales tax now has marketplace facilitator legislation, which moves the duty to collect from the seller to the platform. Whether it applies to you comes down to one question: does the platform take the buyer's money? Platform processes payment Facilitator Amazon, eBay, Etsy, Walmart, TikTok Shop Calculates tax Platform Remits and files Platform You do not register for these sales Send them to Kintsugi anyway, with marketplace: true on the transaction. The tax liability is excluded. Whether their gross sales count toward a state's nexus threshold depends on the state: each nexus period's includeMarketplaceTransactions says. You process payment Storefront Shopify, WooCommerce, your own checkout Calculates tax You Remits and files You Compliance is yours end to end This is the path the four checks describe. Selling on both is the normal case. Marketplace sales being handled by the platform does not exempt you from registering for your direct sales, and it does not undo physical nexus you already have in that state. Segregating facilitated from direct sales in your own reporting is what keeps the two straight at filing time. ## Collection Timeline Sales tax obligations follow a sequence, and every step in it is a date your system should know. Home State Registration Register before your first sale. Most states require a permit regardless of volume once you are operating there. Physical Nexus Registration Register before your first taxable sale into a state where you have presence. Physical nexus carries no grace threshold. Economic Nexus Monitoring Track sales by state and register once you cross. The deadline runs from the crossing date and varies by state, so record the date you crossed, not just the fact that you did. Begin Collection Collect from the effective date of your permit, and apply the rate for the buyer's address on every order from that point. File Returns File and remit on the frequency the state assigns, whether monthly, quarterly, or annually. File even for periods with no sales: most states require a zero return, and missing one draws a penalty on nothing. ## System Architecture Requirements A compliant system needs all of the following. Kintsugi maintains this logic for you: Nexus Tracking Engine Continuously monitor sales across all states, compare them to current thresholds, and flag registration before the deadline rather than after. Key features: Real-time sales aggregation by state Threshold monitoring and alerts Registration deadline tracking Historical data analysis Product Taxability Matrix Map SKUs to state-specific tax rules, including exemptions, reduced rates, and price caps. Key features: SKU-to-taxability mapping State-specific product rules Exemption handling Regular rule updates Rate Calculation Engine Resolve rates from precise geocoding of delivery addresses, applying origin and destination logic per state. Key features: Accurate address geocoding Origin vs destination logic 11,000+ jurisdiction support Real-time rate updates Exemption Certificate Management Collect, validate, and store documentation for exempt sales, with workflows for renewal and expiration. Key features: Certificate collection and storage Validation and verification Renewal tracking Audit trail maintenance Marketplace Sales Segregation Separate facilitated from direct sales in reporting, since the two are filed differently and count differently. Key features: Sales channel identification Separate reporting streams Compliance tracking Audit trail maintenance Comprehensive Audit Trails Keep a record of every calculation, including the nexus determination, the taxability decision, the sourcing rule, and any exemption applied. Key features: Complete calculation history Decision point logging Data integrity checks Compliance reporting ## System Architecture Requirements Sales tax obligations move as your business grows, as states change their laws, and as you add sales channels. The five concepts on this page (the four checks, nexus types, sourcing, marketplace facilitator rules, and collection timing) are what let you build systems that scale with the business instead of being rewritten by the next threshold you cross. ## Next Steps Get Started Ready to implement? Start with the Getting Started Guide and the API Reference. Need Help? Questions about your specific use case? Check our Support Center or contact our team. --- # Product Categories (2026-10-06) How Kintsugi classifies products into categories and subcategories for taxability. Source: https://docs.trykintsugi.com/docs/2026-10-06/guides/product-categories Kintsugi classifies every product into a category and subcategory, which together determine how it is taxed across jurisdictions. When you create or update a product, send the pair as productCategory and productSubcategory. See Create a product for the full request, and List the product category catalog for the complete catalog of values. Search the catalog below to find the right classification for your products. The same data is available programmatically from the List the product category catalog endpoint. ## Reading the catalog from the API GET /products/categories returns one entry per top-level category. Each entry carries a category and a subcategories array, and each subcategory carries a label, a description and an example. The Name column in the table below is the subcategory label. GET /products/categories HTTP/1.1 Host: api.trykintsugi.com Api-Key: Api-Version: 2026-07-21 The category and each label are the exact values that productCategory and productSubcategory accept on Create a product and Update a product. A pair that does not match the catalog returns 400. The catalog is the same for every caller, so it needs a valid API key but no Organization-Id, Connection-Id or Entity-Id selector. You can also name a pair directly on a line of a tax estimate, in place of an externalProductId. The line is priced under that classification without creating a product. ## The catalog Verified against production Oct 8, 2026 · unchanged since Sep 20, 2026 All Digital Misc Physical Services Showing 1–50 of 700 subcategories Digital Name Description Example Audio Books Recordings of books being read aloud, distributed and consumed in digital formats such as MP3 or proprietary app-based files. Audible audiobooks, MP3 audiobooks, Digital book narrations, Downloadable audiobooks, Streaming audiobooks B2B SaaS Software as a Service designed for business-to-business interactions. Enterprise resource planning (ERP) systems. B2C SaaS Software as a Service aimed at consumers. Personal finance management tools. Canned Educational Software Downloaded B2B Pre-existing software for educational purposes, licensed and delivered to educational institutions or businesses via electronic download. Learning Management Systems (LMS downloaded), Classroom software (institutional download), Training simulation software (B2B ESD), Educational game licenses (bulk download), K-12 curriculum software (download) Canned Non-Educational Software Downloaded B2B General-purpose or business-specific pre-existing software (not primarily educational) licensed and delivered to businesses via electronic download. Office productivity suites (B2B download), Accounting software (download license), CRM software (downloaded), Design software (B2B ESD), Project management tools (download) Canned Software Customization Services to alter or add features to existing prewritten software to meet specific user requirements, without changing core code. Configuring modules, Setting user parameters, Creating report templates, Scripting for integration, Workflow adjustments (COTS) Canned Software Downloaded B2B ## The catalog Pre-existing software acquired by businesses through electronic download, for installation on their own systems. Microsoft Office (volume license download), Adobe Creative Suite (B2B download), Accounting software (ESD), CAD software (download), Server software licenses (downloaded) Canned Software Downloaded B2C Pre-existing software acquired by individual consumers via electronic download for installation on their personal devices. Downloaded games, Productivity apps (download), Utility software (ESD), Mobile apps (purchased/downloaded), Creative software (download license) Canned Software Load & Leave B2B Pre-existing software installed by a vendor directly onto a business customer's hardware, where the vendor does not provide ongoing hosting. On-premise ERP installation, Vendor-installed accounting software, Local server application setup, Desktop productivity suite (on-site install), Machine-specific control software Canned Software Load & Leave B2C Pre-existing software installed by a vendor directly onto an individual consumer's device, where the vendor does not provide ongoing hosting. Home productivity software (installed by tech), Anti-virus setup (on-site), Game installation service (local), Educational software (vendor installed), OS installation (by technician) Canned Software Physical Media B2B Pre-existing software delivered to businesses on tangible storage media such as CDs, DVDs, or USB drives. ERP software (on DVD), CAD/CAM on USB, Boxed office suites, Industry-specific software (CD), Archived software (physical) Canned Software Physical Media B2C Pre-existing software delivered to individual consumers on tangible storage media like CDs, DVDs, or USB drives. ## The catalog Games on DVD, OS on USB drive, Productivity suite (CD-ROM), Educational software (boxed), Tax software (physical media) Canned Software Support - Optional - Load & Leave Updates/Upgrades Only Elective ongoing software updates/upgrades for prewritten software (installed on client hardware by vendor), purchased separately (no other support). Optional COTS upgrades (on-prem), Elective version enhancements (local install), Add-on patch service (local COTS), A la carte prewritten software updates (load & leave), Separately purchased upgrade-only plan (local) Cloud or Remote Storage A service model where digital data is stored on third-party servers and accessed via a network like the internet. Dropbox, Google Drive, iCloud, OneDrive, Amazon S3 (personal/business) Computer Use Access Fee Granting permission or providing means to use a computer workstation, often for a specified period or purpose, including shared/public computers. Internet cafe access, Library computer use, Co-working space hot desk, Kiosk computer session, Pay-per-use terminal Custom Software Downloaded Unique software for specific business needs, delivered to client via electronic download for installation on their systems. Bespoke CRM (downloaded), Custom ERP modules (ESD), Tailored B2B app (download), Proprietary analysis tool (download), Custom e-commerce platform (client-hosted) Custom Software Load & Leave Unique software for specific business needs, installed directly onto client's hardware by vendor, without ongoing vendor hosting. Bespoke on-premise ERP, Custom local database app, Tailored B2B desktop tool, Vendor-installed proprietary software, Client-server custom application Custom Software Physical Media ## The catalog Unique software for specific business needs, delivered to client on tangible storage media like CDs, DVDs, or USB drives. Bespoke software on CD (B2B), Custom application (USB delivery), Tailored ERP system (physical media), Proprietary tool (on DVD for business), Custom database app (physical install media) Custom Software Support - Optional - Electronic Updates/Upgrades Only Elective ongoing electronic delivery of software updates and version upgrades for custom-developed software, purchased separately (no other support). Optional custom SW upgrades (ESD), Elective version enhancements (download), Add-on patch service (custom electronic), A la carte custom software updates, Separately purchased upgrade-only plan Custom Software Support - Optional - Load & Leave Updates/Upgrades Only Elective ongoing software updates/upgrades for custom software (installed on client hardware), purchased separately (no other support). Optional custom SW upgrades (on-prem), Elective version enhancements (local install), Add-on patch service (custom local), A la carte custom software updates (load & leave), Separately purchased upgrade-only plan (local) Custom Software Support - Optional - Updates/Upgrades Only Elective ongoing delivery of software updates and version upgrades for custom-developed software, purchased separately (no other support services). Optional custom SW upgrades, Elective version enhancements, Add-on patch service (custom), A la carte custom software updates, Separately purchased upgrade-only plan (custom) Data Access Fees B2B Charges incurred by businesses for the right to access or retrieve information from databases, platforms, or information services. ## The catalog Database subscription fees (B2B), API access charges, Financial data feed fees, Legal research platform access, Market intelligence report access Data Access Fees B2C Charges incurred by individual consumers for the right to access information from online databases, content platforms, or specialized services. Premium content subscription, Online archive access fees, Genealogy database access, Consumer credit report fees, Pay-per-view data services Data Processing B2B Services provided to businesses involving the collection, manipulation, computation, or organization of data, often automated. B2B payroll processing, Claims processing services, Business data entry, Market research data analysis, Batch data conversion (B2B) Data Processing B2C The collection and manipulation of items of data to produce meaningful information, a general term covering various computation or data organization tasks. Data entry, Data conversion, Information processing, Reports, Statistical analysis Data Processing Electronic Output B2B Services for businesses involving automated or manual processing of data, where the results or output are delivered electronically. Electronic payroll processing, B2B data analysis reports (digital), Digital claims processing, E-statements, Cloud data transformation services Data Processing Electronic Output B2C Services involving manipulation or computation of data where final results are delivered in a digital or electronic format. Digital report, E-statement processing, Online data analysis, Cloud data transformation, Electronic data interchange (EDI) Data Processing Physical Output Services involving manipulation or computation of data where final results are delivered in a tangible, physical format. ## The catalog Printed report, Direct mail processing, Check printing services, Physical document archiving, Label printing services Digital Content and Electronic Product Delivery Services Various digital goods, electronic content, and digital products delivered without physical media or storage devices. Digital product taxability varies significantly by state. digital content downloads, electronic product delivery, digital media content, online digital products, electronic content services Digital Gaming Content and Streaming Services Video games and gaming content delivered through digital download platforms, streaming services, or cloud-based gaming systems. Digital product taxability varies significantly by state. downloadable video games, game streaming services, digital gaming content, online game downloads, cloud gaming subscriptions General Digital Goods - No TPP Any Digital good outside of Kintsugi's defined categories Any Digital good outside of Kintsugi's defined categories Hosted Software with Server Off-Premise B2B Software applications provided to businesses over a network, hosted on servers not located at the customer's premises. Salesforce (CRM), Microsoft 365 (Business), Google Workspace, SAP S/4HANA Cloud, Workday Hosted Software with Server Off-Premise B2C Software applications provided to individual consumers over a network, hosted on servers not located at the consumer's premises. Streaming services (Netflix/Spotify software), Online games (cloud-hosted), Personal cloud storage apps, Web-based email clients, Freemium SaaS (consumer) IaaS B2B Infrastructure as a Service for businesses, offering virtualized computing resources like virtual machines, storage, and networks. ## The catalog AWS EC2 instances (business), Azure Virtual Machines (B2B), Google Compute Engine (enterprise), Cloud storage (business tier), Dedicated hosting (IaaS) IaaS B2C Infrastructure as a Service for individual consumers, offering access to fundamental computing resources like virtual servers or storage. Personal cloud servers (VPS), Consumer cloud storage, Hobbyist virtual machines, Developer sandbox (IaaS), Personal VPN (self-hosted IaaS) Installation/Setup Fees for Hosted Software B2B Charges billed to a business specifically for initial installation, configuration, or setup of an ASP or hosted software service. SaaS onboarding fee, Hosted software setup charge, ASP configuration fee, Cloud application deployment fee, Initial user setup (ASP) Installation/Setup Fees for Hosted Software B2C Charges billed to an individual consumer specifically for initial installation, configuration, or setup of an ASP or hosted software service. Consumer SaaS setup fee, Hosted game installation charge, Personal cloud setup assistance, Streaming service activation fee, Online app configuration support Optional Maintenance Agreement with TPP Sales An elective service contract for future repair or maintenance of Tangible Personal Property (excluding software), purchased with the TPP. Extended hardware warranty, Appliance service plan, Equipment maintenance contract, Furniture protection plan, Vehicle service agreement (optional) PaaS B2B Platform as a Service for businesses, offering a platform for developing, running, and managing applications without managing infrastructure. AWS Elastic Beanstalk (business), Azure App Service (B2B), Google App Engine (enterprise), Heroku (professional tier), Salesforce Platform PaaS B2C ## The catalog Platform as a Service for individual consumers/developers, offering a platform for creating, deploying, and managing personal applications. Free/hobbyist PaaS tiers, Developer PaaS (individual accounts), App building platforms (consumer), Cloud development environments (personal), Serverless functions (personal use) Purchased Digital Games with Permanent Ownership Rights Digitally downloaded video games with permanent ownership rights, offline access, and full game content without subscription requirements. Digital product taxability varies by state. permanently owned digital games, full game downloads, digital game purchases, owned electronic games, permanent digital gaming content Software B2B Computer programs and associated documentation designed for and licensed to businesses for various operational or productivity functions. ERP systems, CRM software, Business analytics tools, Accounting software, Project management software Software B2C Computer programs and associated documentation designed for and licensed to individual consumers for personal use, entertainment, or productivity. Video games, Personal productivity apps, Antivirus software (consumer), Photo editing software (personal), Mobile apps (consumer) Subscription Based Digital Gaming Services Video games accessed through subscription services, streaming platforms, or temporary downloads with limited ownership and access rights. Subscription service taxability varies. gaming subscription services, game streaming access, temporary game downloads, subscription gaming platforms, limited-access digital games System Software Software designed to operate and manage computer hardware and provide a platform for running application software. ## The catalog Operating systems (Windows/macOS/Linux), Device drivers, Utility programs, Firmware, Boot loaders Misc Name Description Example Books - Coupon or Discount Book Bound collections of vouchers or certificates offering discounts, special deals, or free goods/services from various businesses. Entertainment Book, Local coupon books, Restaurant discount books, Travel coupon books, Fundraiser coupon books Credit card processing fees Fees levied by credit card companies for various services. Annual fees, late payment fees. Discount - Manufacturer Rebate A partial refund by a product's manufacturer to customers after purchase, where the initial item sale was taxable. Mail-in rebate, Instant rebate (manufacturer), Cashback offer (mfr.), Product registration rebate, Loyalty rebate (mfr.) Discounts - Cash Payment (vs Credit, Retailer) A price reduction offered by a retailer to customers who pay with cash instead of credit card or other non-cash methods. Cash discount (at gas station), Pay-by-cash savings, Surcharge avoidance (cash), Dual pricing (cash lower), Cash-only price Discounts - Cash (Retailer Early Payment, After POS) A price reduction by a retailer for customer paying an invoice early, applied after the initial point of sale. 2/10 net 30 terms, Prompt payment discount, Early settlement discount, Invoice credit (early pay), Account balance reduction Previous 1 2 … 14 Next --- # Integrating Kintsugi's API (2026-10-06) How a Kintsugi integration fits together: the four touchpoints, the shared record pattern, checkout, and the transaction record Source: https://docs.trykintsugi.com/docs/2026-10-06/guides/integrating-kintsugis-api A Kintsugi integration is smaller than it first looks. Four surfaces in your product each make one call, two of them before a sale and two of them at it. This guide is the map: what talks to what, in what order, and why. For request shapes and endpoint details, each section links down to the guide that covers it. This page covers the Tenanted API. Send Api-Key: on every request, and pin Api-Version to the release you build against so your integration never depends on a default. The examples here pin 2026-07-21; the API changelog lists what each newer release changes. Paths carry no /v1 prefix, and every field is camelCase. ## Understanding Your Integration Context Three questions shape everything that follows. When do sales tax calculations currently happen in your software? The point in your flow where tax is calculated today is where the estimate call goes tomorrow. Common answers: the checkout page, payment processing, order confirmation, or a subscription billing run. Most integrations do both jobs: transaction sync for compliance, plus live estimation at checkout. Build transaction sync first, then turn on estimation once transactions are flowing. See Planning an Integration for the full model. Are you replacing another tax provider? Map your existing calls to Kintsugi's endpoints before you write anything, and pay attention to where the data models differ rather than where they match. Migrating from Avalara or TaxJar covers the mapping. Are you building from scratch? Start with the transaction record and work backwards. Plan the initial catalog and customer sync as a batch job, design retry and error handling before you need them, and add real-time estimation once the compliance path is solid. ## Core Integration Architecture Every integration comes down to four touchpoints. Nothing else in your stack needs to know Kintsugi exists. In your product The call it makes Customer management Signup, account settings, address edits Create and update customers Reference data Before the sale Product catalog New SKUs, category and description changes Create and update products Reference data Before the sale Checkout Cart totals, before payment Estimate tax At the sale Nothing stored Order processing Once payment clears Create a transaction At the sale The record of what you owe What Kintsugi does with it Tax calculation Nexus tracking Filing preparation Build the two reference-data rows first, so customers and products exist before the first sale names them. ## Customer and Product Records Customers and products are the same problem twice: a record in your system that Kintsugi needs a copy of, keyed on your own identifier. Learn the pattern once, then read the two differences. 1 Something changed on your side A customer signs up or edits an address; a SKU is created or its classification changes. Fire on the write rather than on a nightly job, because tax depends on current data. 2 Create it, keyed on your externalId POST /customers and POST /products are idempotent on externalId and source, so a retry is safe. NEW → Created Kintsugi stores the record and returns it with its id. SEEN BEFORE → Existing record returned 200 instead of a duplicate. A match you previously deleted is restored rather than duplicated. 3 Update it with PATCH Create never changes an existing record. To change one, send only the fields that moved to PATCH /customers/{customerId} or PATCH /products/{productId}. 4 Store the Kintsugi id Keep the returned id on your own record. It is what you address the PATCH to, and what you pass as customerId when you create an exemption. Delta · customers Exemptions A separate object on its own schedule, since a buyer often sends a certificate long after signup. When a certificate arrives Create the exemption Attach the certificate PDF to it Watch for The exemption takes the customer's customerId, the id you stored in step 4. Delta · products Classification You pick the category and subcategory from Kintsugi's catalog. Both are required on create. Re-send with PATCH when It moves to a different category or subcategory Watch for A pair the catalog does not recognize returns 400. On a recategorize, taxExempt is derived from the new category. ## Customer and Product Records For exemptions, the two calls are Create an exemption and Upload an exemption certificate. For products, productCategory and productSubcategory come from Kintsugi's catalog. Reference by your own IDs. An estimate names products with externalProductId on each line and the buyer with externalId on the customer object. A transaction names products with externalProductId on each item and the buyer with customer.externalId. A stable identifier on your side is what holds the whole integration together. Full request shapes are in Product and Customer Records. Exemptions without a customer record. For a one-off that belongs to no customer, set exempt: true on the estimate line instead. For the initial load, run the sync as a batch job with retries. Because create is idempotent on externalId and source, a retried request never leaves you with a duplicate. Every error comes back in one envelope with a code, a message, a requestId and a list of field errors, so log the requestId with each failure. ## Tax Estimation Integration Tax estimation runs during checkout, where the customer needs an accurate total before they pay. It is usually the most latency-sensitive call in the integration, and the only one that stores nothing. 1 Cart and shipping address Tax needs both. The line items decide taxability, the address decides the rate, and until you have an address there is no estimate to show. 2 Resolve the address first Rates go down to the local level, so an unresolved address gives a rate you cannot defend. Validate, then estimate against the corrected version. INVALID → Surface the correction to the buyer at checkout rather than silently substituting it. They are the only one who knows where the parcel goes. 3 Estimate the tax Send the line items and the resolved address. You get amounts broken out by jurisdiction. 4 Display it and take payment Charge the buyer the estimated tax. Re-estimate if anything in the cart or the address moves between display and payment. Payment clears, so record it Now create the transaction. That is the next section, and it is the only step that changes what you owe. If payment fails, stop. No transaction, no liability: an abandoned checkout leaves nothing behind in Kintsugi. Estimates are safe to repeat. POST /tax-estimations stores nothing and the estimate is not retrievable afterwards, so you can call it every time the cart or the address changes. Debounce address input, and reuse a result while both are unchanged. The estimate validates its addresses as it runs: one that cannot be validated returns 400, and an address-validation outage returns 503, which you can retry. Sales Tax Calculations covers the request, the response breakdown, and the zero-tax cases. ## Transaction Reporting Integration Once payment clears, the sale becomes a transaction record. This is the call that changes what you owe. What goes in The customer customer.externalId, plus name, email and companyName where you hold them. Omit customer and the sale goes to the organization's shared unattributed-sales customer. Line items Each names the product by externalProductId, with its date, quantity and amount. Addresses Jurisdiction is resolved from these, so send a complete SHIP_TO. Tax charged What the buyer actually paid, as taxAmountImported on each item. Create the transaction POST /transactions once per order, keyed on your order ID as externalId. It answers 202 Accepted. Re-sending the same externalId updates the existing transaction rather than creating a second. What comes back Recorded now The transaction is stored immediately, with processingStatus QUEUED. Tax calculated afterwards The first response shows the calculated tax at "0.00". Sales you never send are sales Kintsugi cannot see. Exempt, zero-tax and marketplace orders all belong here too. POST /transactions HTTP/1.1 Host: api.trykintsugi.com Content-Type: application/json Api-Key: Api-Version: 2026-07-21 { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "description": "Order 2001", "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "country": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } The first response looks like this: ## Transaction Reporting Integration { "id": "tran_12345", "externalId": "order-2001", "status": "COMMITTED", "processingStatus": "QUEUED", "totalAmount": "100.00", "totalTaxAmountCalculated": "0.00", "totalTaxLiabilityAmount": "0.00", "addressStatus": "UNVERIFIED" } The returned id is not fetchable straight away. GET /transactions/{transactionId} answers 404 until processing completes, so poll it rather than treating the first 404 as a failure. Flag a marketplace order with marketplace: true; its tax liability is excluded. Whether its gross sales count toward a state's nexus threshold depends on the state, and each nexus period's includeMarketplaceTransactions says which. Reconciling later. The transaction is keyed on your order ID, which is also how you find it again: the search filter on List transactions matches externalId. Syncing Transaction Records covers status and backfill, and Handling Refund Transactions covers credit notes. ## Common Integration Patterns Where you place these four calls depends on what you are building. E-commerce: estimate tax during checkout, create the transaction as soon as payment clears. The most common shape. SaaS and subscriptions: estimate per billing cycle rather than per page view, and create transactions in a batch after the billing run. Marketplaces: calculate per seller, report centrally, and account for marketplace facilitator rules, which decide whether the tax is yours to collect at all. See US Sales Tax for Developers. Whichever shape fits, the ordering constraint is the same: reference data first, then transactions, then live estimation on top. ## Implementation Checklist [ ] API keys created and authentication working end to end [ ] Api-Version pinned to your release on every request [ ] An Organization-Id, Connection-Id or Entity-Id selector sent wherever your key reaches more than one organization [ ] Customers synced, with exemption certificates attached where they exist [ ] Product catalog synced, every item carrying a productCategory and productSubcategory [ ] Kintsugi IDs stored against your own records [ ] Address validation wired in ahead of estimation [ ] Estimation called at checkout, with retry on 503 and graceful degradation [ ] Transactions created on payment, keyed on your order ID, with the 202 handled as accepted rather than finished [ ] Tested against exempt customers, zero-tax states, and multi-jurisdiction addresses Transaction sync first, then estimation. Start with customers, products, and transaction reporting. Once that is stable, add the estimation workflow for real-time checkout totals. See Planning an Integration for the full model. ## Next Steps API Reference Endpoint documentation, request formats, and response structures in the API Reference. SDKs Our SDKs for Python, TypeScript, Java, PHP, and Ruby cover the v1 API. For the Tenanted API, call the HTTP endpoints directly. --- # Migrating from Avalara/TaxJar to Kintsugi (2026-10-06) Map your existing Avalara or TaxJar integration to Kintsugi's endpoints, move your data, and cut over without breaking a filing period Source: https://docs.trykintsugi.com/docs/2026-10-06/guides/migrating-from-avalara-taxjar Migrating tax providers is mostly a mapping exercise plus one judgment call. The mapping is small: four concerns, four replacements. The judgment call is how much you want to find out before the old system is switched off. This guide covers both, then the data you need to bring with you. This page maps your integration to the Tenanted API. Send Api-Key: on every request, and pin Api-Version to the release you build against. The examples here pin 2026-07-21; the API changelog lists what each newer release changes. Paths carry no /v1 prefix, and every field is camelCase. Cut over at the start of a filing period and keep the old system's records. A period split across two engines is the one thing that makes a return genuinely hard to reconcile. ## Understanding Key Differences Three differences change how you build, rather than just which URL you call. Estimating versus recording All three providers can quote tax without recording it, but they express it differently, and this is the difference that shapes your integration. Avalara uses one endpoint for both, switched by DocumentType. A type ending in Order (such as SalesOrder) is a temporary estimate that is not preserved; a type ending in Invoice is a permanent recorded transaction. TaxJar uses two endpoints: POST /v2/taxes calculates and stores nothing, POST /v2/transactions/orders records. Kintsugi also uses two: POST /tax-estimations stores nothing, POST /transactions is the record. The record answers 202 Accepted and calculates tax afterwards, so the first response shows processingStatus QUEUED with the calculated tax at "0.00". If you are coming from Avalara, the cleanest mental translation is that your SalesOrder calls become POST /tax-estimations and your SalesInvoice calls become POST /transactions. If you are coming from TaxJar, the two calls you already make map one to one. Data model mapping Kintsugi keys records on your identifiers through externalId, so your own IDs stay the source of truth. Avalara scopes most objects to a company and identifies transactions by a transaction code; TaxJar identifies orders by transaction_id. In all cases, put your existing identifier in Kintsugi's externalId and the reconciliation stays trivial. Creating a customer or product is idempotent on externalId and source, and re-sending a transaction with the same externalId updates it rather than creating a second. Product classification ## Understanding Key Differences Avalara assigns tax codes to items you create under a company. TaxJar has no product records at all: you send a product_tax_code on each line item, chosen from its category list. Kintsugi keeps a product catalog, and each product carries a productCategory and a productSubcategory drawn from Kintsugi's own taxonomy. Kintsugi maintains what each category means in every jurisdiction, so you classify once rather than tracking rule changes. Tax codes are not portable. An Avalara tax code or a TaxJar product_tax_code has no Kintsugi equivalent, both category fields are required on every product you create, and a pair the catalog does not recognize returns 400. Budget a classification pass over the catalog as real migration work, not a data copy. ## API Endpoint Mapping Find the call you make today in the left two columns and read across. Avalara TaxJar Kintsugi Tax calculation Quote tax for a cart POST / api/ v2/ transactions/ create DocumentType: SalesOrder POST / v2/ taxes POST / tax-estimations All three quote without recording. Avalara does it on the same endpoint that records, switched by document type: a type ending in Order is a temporary estimate that is not preserved. TaxJar and Kintsugi use a separate call that stores nothing. Transaction recording Commit the completed sale POST / api/ v2/ transactions/ create DocumentType: SalesInvoice POST / v2/ transactions/ orders POST / transactions This is the call that changes your liability, so if you port one thing exactly, port this one. An Avalara type ending in Invoice is the recorded counterpart of the row above. Customer management Buyers and their exemptions POST / api/ v2/ companies/ {companyId}/ customers POST / v2/ customers POST / customers Key it on the customer ID you already use, so the mapping stays obvious during a parallel run. Exemptions are their own object in Kintsugi: POST /exemptions carries the customerId, and the certificate is uploaded to the exemption. Product management Catalog and tax categories POST / api/ v2/ companies/ {companyId}/ items GET / v2/ categories Read-only list POST / products TaxJar has no catalog to export: it takes a product_tax_code per line item, so this row is a build rather than a migration. Kintsugi wants its own productCategory and productSubcategory, listed by GET /products/categories. ## API Endpoint Mapping Endpoints map cleanly; tax codes do not. Avalara tax codes and TaxJar product_tax_code values have no Kintsugi equivalent, every product you create needs a productCategory and productSubcategory, and a pair the catalog does not recognize returns 400. Budget a classification pass over the catalog before you rely on Kintsugi's rates. Kintsugi paths are verified against the spec that generates this site's API Reference. Competitor paths are current as of publication and taken from Avalara's and TaxJar's own SDKs; check them against your provider's reference before you write the mapping into code, since only they control those. ## Migration Strategy All three approaches end in the same place. They differ in how much you find out before the old system is gone. Option A Big bang Switch everything on one date. How it goes Point every call at Kintsugi Turn the old system off You learn what broke in production Risk Highest Time Shortest Option B Parallel run Run both, compare, then switch. How it goes Call both, charge the old one Diff the amounts, chase the gaps Switch once the diff is explainable Risk Low Time Medium Option C Gradual rollout Move one slice at a time. How it goes Start with one region or state Then one product line Widen until nothing is left Risk Lowest Time Longest Whichever you pick, cut over at the start of a filing period and keep the old system's records. A period split across two engines is the one thing that makes a return hard to reconcile. We recommend the parallel run for anything already in production. It is the only option that lets you compare real amounts on real orders before the old system stops being your safety net, and the cost is a few weeks of double-calling rather than a rewrite. ## What to Bring With You Nexus thresholds are measured over rolling windows, so Kintsugi needs history to tell you where you already have obligations. Starting cold means starting with an empty exposure map. Products and customers Create these first: each transaction item names its product by externalProductId. Creates are idempotent on externalId and source, so a batch job can retry a failed request without leaving a duplicate. Store the Kintsugi id against your own record as you go. Exemption certificates An exemption is its own object. POST /exemptions carries the customerId it belongs to, along with the exemptionType, the startDate, and the buyer's registration details such as fein and salesTaxId. The certificate itself is a PDF of up to 10 MB, uploaded to the exemption with POST /exemptions/{exemptionId}/certificates. To move many at once, POST /exemptions/bulk creates up to 100 in one all-or-nothing request. Historical transactions Sync enough history to cover each state's nexus measurement window, and send each transaction's real date: it decides which filing period the transaction lands in. For a bulk backfill, CSV upload is usually faster than replaying records through the API. Registrations Record where you are already registered with POST /registrations, sending the registrationDate each permit takes effect. Kintsugi calculates tax where a registration is active, so a missing registration reads as a state you do not collect in. Keep externalId values identical to the ones your old integration used. This is what makes a parallel run comparable order by order, and what makes reconciliation possible afterwards. ## Common Migration Challenges Address validation Rates resolve to the local level, so an unresolved address produces a rate you cannot defend. Both providers offer address validation and so does Kintsugi, through POST /addresses/validate and POST /addresses/suggestions. Solution: Validate the address before you estimate, and estimate against the corrected version. The estimate validates its addresses too, and one that cannot be validated returns 400. See Sales Tax Calculations for where this sits in the checkout sequence. Exemption certificates Exemption workflows differ more than the endpoints suggest. Kintsugi models an exemption as a separate object owned by a customer rather than a flag on one. Solution: Create the customer first, then the exemption against its customerId, then attach the certificate. A one-off exemption that belongs to no customer record rides on the estimate line instead, as exempt: true. Product tax code mapping This is the part of the migration that is not mechanical. Neither provider's codes carry over. Solution: Pull the current taxonomy from GET /products/categories and map your catalog to it rather than hardcoding values. Start with the SKUs that carry the most revenue, since a misclassification there costs the most, and check the result against the old system's rates during a parallel run. Reconciling the two systems During a parallel run you need to know which differences matter. Rounding and jurisdiction rollup differences are expected; a different taxability decision is not. ## Common Migration Challenges Solution: Diff at the line level rather than the order total, so a difference points at a product or an exemption rather than at a number. Each estimate line echoes the externalId you sent, so lines match up one to one. Investigate any line where one engine taxes and the other does not before you switch traffic. ## Validation Checklist Before cutover: [ ] Estimation implemented, with address validation ahead of it [ ] Transaction creation implemented, keyed on your existing order IDs, with the 202 handled as accepted rather than finished [ ] Customers synced, with exemptions and certificates attached [ ] Catalog synced, every product classified against Kintsugi's taxonomy [ ] Historical transactions backfilled across each state's measurement window [ ] Existing registrations recorded with their effective dates [ ] Api-Version pinned to your release on every request [ ] Retry logic in place, and error logging that keeps each error's requestId [ ] Parallel-run diffs explained at the line level, not just the total [ ] Rollback plan documented, with the old system's records retained ## Post-Migration Stop maintaining tax rules Kintsugi tracks jurisdiction rule changes against your product categories, so a rate or taxability change needs nothing from you. Update a product only when your own classification changes. Estimate freely Because estimates record nothing, you can call the endpoint every time the cart or the address changes, then create the transaction once payment clears. See Integrating Kintsugi's API for where each call belongs. ## Next Steps API Reference Request formats and response structures in the API Reference. Support Migrating a large or unusual integration? Our Support Team has done this before. --- # File Upload (2026-10-06) Import sales transactions from a CSV file, and the columns the importer reads Source: https://docs.trykintsugi.com/docs/2026-10-06/guides/file-upload File upload imports sales transactions from a CSV, which is the fastest way to bring in history when you are onboarding or backfilling a period. Uploaded transactions behave exactly like ones created through the API: they count toward nexus, feed compliance reporting, and land on the right return at filing time. This page is the column reference. Download the template from the app, or with Download a CSV import template, then use the tables below to fill it in. CSV column names are snake_case, such as transaction_external_id. They describe the file, not the API, so they do not change to camelCase on the Tenanted API. The camelCase names appear only in API responses, such as the resultData rows that Validate a CSV file returns. ## Before You Start Five columns have to be in the file A file missing any of these is rejected before any row is read. The first four need a value on every row. amount is required as a column so that a file without it cannot book every line at 0.00. Every other column can be left out entirely, and the value falls back to the default listed on its row. Leaving one out is not the same as including it and leaving cells blank, which the next two cards cover. transaction_external_id date customer_id product_external_id amount Omitting a column is safe. Blanking a cell is not A default only applies when the column is absent from the file. Once you include a column, the upload validator expects a value in it, and it is stricter than the defaults suggest. Column absent The documented default applies to every row. This is the safe way to skip a column you have no data for. Column present, cell empty Rejected for operation, and a conflict on any transaction-level column where another row of the same transaction does carry a value. Delete the column, or fill it in on every row. One transaction, many rows, identical values A multi-line sale is several rows sharing one transaction_external_id. Only the line item columns are allowed to differ between them. Every transaction-level column you include has to carry the same value on every row, including the addresses, the buyer, the date, status, currency, transaction_type and operation. Filling a column in on the first row and leaving it blank on the rest is the most common way to trip this, because an empty cell counts as a different value. The error names the column and the row it first saw: Inconsistent 'transaction_type': '' vs 'SALE'. ## Before You Start Save the file as text, not as a spreadsheet Format every cell as General before exporting. A cell typed as Date or Number is re-serialized on save, which is the most common reason a file that looks correct fails validation. Postal codes are the other one: a leading zero has to survive the export. Reading the badges Required A value in every row. Conditional Required in a stated case. The rule is on the row. Optional Leave the column out and the default applies. The downloadable template carries two columns the importer does not read. total_amount is ignored because transaction totals come from the line items, so fill in amount and tax_amount per row instead. source is ignored too: each transaction takes its source from the import itself. On the Tenanted API, an import's source is the source you send to the Imports endpoints, and it reads back as transactionSource. ## Transaction Columns These describe the sale. Every row of a multi-line sale repeats them, and rows sharing a transaction_external_id are read as line items of one transaction. Identity, type and date 9 columns transaction_external_id Required Your own id for the transaction. Kintsugi keys the record on it. e.g. in_ctvrAUrbiRdSywvQ Alphanumeric, underscores, hyphens, spaces Minimum length 1 Unique per transaction. Rows sharing an id are read as line items of the same sale. related_external_id Conditional The original transaction's id, when this row credits an earlier sale. e.g. PCR_ctvrAUrbiRdSywvQ Required when transaction_type is FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE. A row cannot reference itself. transaction_type Optional What kind of transaction the row represents. e.g. SALE Defaults to SALE Accepted values SALE FULL_CREDIT_NOTE PARTIAL_CREDIT_NOTE TAX_REFUND Both credit-note types require related_external_id. Transaction-level, so every row of a multi-line sale needs the same value. status Optional Where the transaction sits in its lifecycle. e.g. COMMITTED Defaults to COMMITTED Accepted values COMMITTED PENDING CANCELLED FULLY_REFUNDED PARTIALLY_REFUNDED INVALID and ARCHIVED are set by Kintsugi and rejected on import. Transaction-level, so repeat it on every row of a multi-line sale. operation Conditional What the importer should do with the row. e.g. IMPORT Defaults to IMPORT when the column is absent Accepted values IMPORT UPDATE ARCHIVE Required as soon as the column is in the file. A blank cell is rejected outright rather than falling back to IMPORT, so leave the column out or fill it in on every row. date Required When the transaction took place. e.g. 2024-03-23T00:00:00 The template uses YYYY-MM-DDT00:00:00 ## Transaction Columns Format the cell as General. A cell typed as Date is rewritten on save and the row fails. currency Optional Currency for every amount on the row. e.g. USD Any ISO 4217 code Defaults to USD Transaction-level, so repeat it on every row of a multi-line sale. description Optional Free text describing the transaction. e.g. Heirloom Ring Size 8.5 14K Max 1000 characters marketplace Optional Whether a marketplace facilitator collected the tax on this sale. e.g. FALSE TRUE, FALSE, true, false, 1, 0, t, f Defaults to FALSE The buyer 5 columns customer_id Required Your own id for the buyer. Exemptions attach to it. e.g. cust_cCMVtrsfoUV Alphanumeric, underscores, hyphens, spaces Max 100 characters Transaction-level, so every row of a multi-line sale needs the same buyer. customer_name Optional The buyer's full name. e.g. Faith Ortega Max 200 characters customer_email Optional The buyer's email address. e.g. michele45@example.com Any valid email address Max 200 characters customer_company_name Optional The buyer's registered or legal business name. e.g. Example Company Inc. Max 200 characters tax_id Optional The buyer's registration number. Max 100 characters Transaction-level, so every row of a multi-line sale needs the same value. ## Address Columns Addresses decide the rate, so this is the part of the file worth checking twice. A postal code resolves to a local jurisdiction; a state on its own does not. The one rule Every row needs a postal code and a country from one side or the other. Which side is up to you, but you cannot leave both empty. Either ship_to_postal_code + ship_to_country Or bill_to_postal_code + bill_to_country Ship to 7 columns ship_to_country Conditional The recipient's country. e.g. US Max 100 characters Required unless bill_to_postal_code and bill_to_country are both present. A country of PR is read as state PR in the US. ship_to_postal_code Conditional The recipient's postal code. This is what resolves the local rate. e.g. 21830 US: 5-digit ZIP or ZIP+4 Max 50 characters Checked when the country is US or blank. A 4-digit code is accepted and gets its leading zero back, but exporting the column as text is safer. ship_to_state Optional The recipient's state or province. e.g. CO US: 2-letter code or full state name CA: 2-letter province code ship_to_city Optional The recipient's city. e.g. Aurora ship_to_street_line_1 Optional First line of the street address. e.g. 811 Eric Flat Suite 183 Max 1000 characters ship_to_street_line_2 Optional Second line of the street address. e.g. Apt 1606 Max 1000 characters ship_to_phone Optional The recipient's phone number. e.g. +1 665-869-8307 Max 50 characters Bill to 7 columns bill_to_country Conditional The billed party's country. e.g. US Max 100 characters Required unless ship_to_postal_code and ship_to_country are both present. A country of PR is read as state PR in the US. bill_to_postal_code Conditional The billed party's postal code. This is what resolves the local rate. e.g. 21830 ## Address Columns US: 5-digit ZIP or ZIP+4 Max 50 characters Checked when the country is US or blank. A 4-digit code is accepted and gets its leading zero back, but exporting the column as text is safer. bill_to_state Optional The billed party's state or province. e.g. CO US: 2-letter code or full state name CA: 2-letter province code bill_to_city Optional The billed party's city. e.g. Aurora bill_to_street_line_1 Optional First line of the street address. e.g. 811 Eric Flat Suite 183 Max 1000 characters bill_to_street_line_2 Optional Second line of the street address. e.g. Apt 1606 Max 1000 characters bill_to_phone Optional The billed party's phone number. e.g. +1 665-869-8307 Max 50 characters ## Line Item Columns One row per line item. The product columns drive classification, and the money columns are what your filings reconcile against. The product and the money 10 columns product_external_id Required Your own id for the product, usually the SKU. e.g. F80-BRW Alphanumeric, underscores, hyphens, spaces Max 200 characters product_name Optional The product's name. e.g. Product Name 9 product_description Optional The product's description. e.g. Product Description 9 line_item_id Optional Your own id for this line of the transaction. e.g. il_lQtcAcqhLGPQZhSa Max 200 characters amount Conditional What this line came to, after discounts and excluding tax. e.g. 550.51 Commas allowed, no currency symbols A blank cell is 0.00 The column has to be in the file. Transaction totals are summed from these, so this is the figure that has to reconcile. tax_amount Optional Tax collected on this line. e.g. 1.69 Defaults to 0.00 quantity Optional How many units this line covers. e.g. 14 A value below 1 is rejected Defaults to 1 discount_amount Optional Discount applied to this line. e.g. 0.69 Defaults to 0.00 When present it has to be greater than 0 and no more than amount. Since amount is already net of discounts, this column records the discount rather than applying it. exempt Optional Whether this line is exempt from tax. e.g. FALSE TRUE, FALSE, true, false, 1, 0, t, f Defaults to FALSE customer_exempt Optional Whether the buyer holds an exemption covering this sale. e.g. FALSE TRUE, FALSE, true, false, 1, 0, t, f Cannot be TRUE when exempt is also TRUE: the row has to say whether the product or the buyer is the reason. ## Line Item Columns product_name and product_description are optional columns that do real work: Kintsugi classifies the product from them, and classification is what decides taxability per state. A file with bare SKUs imports cleanly and prices badly. ## Importing a Refund A refund is a credit note row that points at the original sale. 1 Mark the row as a credit note Set transaction_type to FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE. That is what makes the next column required. 2 Point it at the original Put the original sale's id in related_external_id, and give the credit note its own transaction_external_id. A row cannot reference itself. PCR_ Credit note ids are conventionally the original id behind a PCR_ prefix, which keeps the pair legible in an export. Set the original's status PARTIALLY_REFUNDED and FULLY_REFUNDED are both accepted values of status, for the original sale's rows. Recording refunds through the API instead? See Handling Refund Transactions. ## After the Upload Kintsugi validates the file before importing any of it, and errors come back per row and per column, so a rejected file tells you which cell to fix rather than just failing. The same checks are available through the Tenanted API's Imports endpoints: Validate a CSV file checks a file's contents before you upload it. It always answers 200; read isValid and errors to see whether the file passed. Get an import by id reports an import's status and its row counts, including validRowCount and invalidRowCount. Get a download link for an import's error artifact returns the validation errors as a file, or the row-processing errors with phase=import. Import the validated rows imports the rows that passed. submitMode ALL requires every row to have passed validation; VALID_ONLY imports the rows that passed and skips the rest. ## Related Resources Getting Started Set up your account and import historical data. Syncing Transaction Records Prefer automation? Sync transactions programmatically instead. Migrating from Avalara or TaxJar Moving providers? CSV upload is usually the fastest way to backfill history. Product Categories How Kintsugi classifies products, which is what the product columns feed. --- # 1. Planning An Integration (2026-10-06) Understand L1 (transaction sync) and L2 (tax engine) integration levels, and map endpoints to your workflow Source: https://docs.trykintsugi.com/docs/2026-10-06/api-guides/planning-an-integration The best integrations are decided before they are coded. Kintsugi uses a two-level integration model: Level 1 (L1) is transaction sync, the foundation for every integration, and Level 2 (L2) adds real-time tax calculation. This guide helps you pick your level, sequence the work, and know which Tenanted API endpoint belongs at which point in your workflow. ## Understanding Integration Types Every integration sends transaction data. What changes is whether Kintsugi also calculates tax at checkout and files on your behalf. LEVEL 1 Baseline Transaction sync Send completed transactions so Kintsugi can determine nexus and prepare filings. Endpoints /products /customers /transactions CALC ONLY No filing Tax calculation Real-time tax at checkout or billing, while you file and remit yourself. Endpoints /tax-estimations /transactions Transaction data is still required. It is how nexus is determined. LEVEL 2 Full Tax + compliance Level 1 plus the tax engine: calculate at checkout and stay filing-ready. Adds to level 1 /tax-estimations Turn on after transaction sync is running. L1 first, always. L1 comes first: Establish transaction sync, then enable L2 when you need Kintsugi to calculate and collect tax at checkout. On a platform connection, Enable tax collection on a connection turns on tax calculation (L2), and it returns 400 if the connection is not ready for tax calculation. ## Choosing Your Integration Pattern Your choice comes down to two questions: where you are in your compliance lifecycle, and who owns filing. L1: Transaction Sync Only Transaction sync is the foundation. This pattern records completed sales for compliance tracking without real-time tax calculation. You will use: POST /products to sync your product catalog POST /customers (optional) if you track exempt customers POST /transactions to record completed sales Historical data requirement: For transaction sync integrations, send historical transactions covering the previous full calendar year through today. Kintsugi uses that history to determine nexus liability. Without it, we cannot pinpoint when you crossed economic nexus thresholds or calculate your compliance obligations accurately. L1 fits teams moving off manual compliance processes, syncing after the fact from an accounting system, or building an audit trail across existing sales. In platform integrations, this is the Level 1 connection, often labeled "Read Only" or "Compliance" mode. Tax Calculation Only This pattern returns real-time tax during checkout without using Kintsugi for filing and remittance. You will use: POST /products to create product records with tax classifications POST /customers (optional) if you sell to exempt entities such as nonprofits or resellers POST /tax-estimations to calculate tax before collecting payment Transaction data is still required: Even when Kintsugi is not handling filing, tax calculation depends on nexus, and Kintsugi determines nexus from your transaction data. Tax calculation without transaction sync works only when nexus and compliance are managed elsewhere and you need Kintsugi purely for rate lookup. ## Choosing Your Integration Pattern When to use this pattern: You are replacing another tax calculation service, your compliance team files separately, or you are a marketplace calculating tax for sellers without owning their compliance. The tax estimation endpoint returns tax amounts, rates, and a per-line-item tax breakdown without recording anything. Nothing is stored and the estimate cannot be retrieved afterwards, which makes it a natural fit for shopping carts, subscription billing platforms, and point-of-sale systems. L2: Transaction Sync + Tax Calculation (Both) Most production integrations use both: L1 for compliance plus the tax engine for checkout. Calculate tax during checkout for accurate pricing, then sync the completed transaction for compliance tracking. In platform integrations, L2 is the Level 2 connection, often labeled "Tax Engine" mode, enabled after L1 is established. Choose Your Path Two questions decide the integration. Start at the left. Q1 Do you need compliance tracking? Nexus monitoring, registrations, filings YES Kintsugi tracks and files L1 Start with transaction sync Required first. Products, customers and transactions. then Q2 Calculate tax at checkout? YES → Level 2: tax + compliance Add the tax engine on top of L1. NO → Level 1 only Sync now, enable L2 whenever you're ready. NO You file and remit yourself Q2 Need tax calculation only? YES → Tax calculation only Plus transaction data, so nexus stays accurate. NO → Talk through the use case Reach out and we'll scope the integration with you. ## Historical Transaction Requirements If you are building an L1 or L2 integration, or using tax calculation with Kintsugi-managed nexus, send historical transaction data covering the previous full calendar year through today. Why Historical Data Matters Kintsugi determines nexus liability by analyzing your sales volume and transaction counts across jurisdictions. Economic nexus thresholds (commonly $100,000 in sales or 200 transactions) are evaluated over a rolling 12-month period or a full calendar year, depending on the state. Some states use their own fiscal year: New York, for example, runs March 1st through the last day of February. Without history, we cannot: Determine when you crossed nexus thresholds Calculate accurate compliance start dates Prepare accurate tax filings Track nexus status changes over time What if I don't have historical data? Kintsugi will still track your future transactions and calculate nexus going forward. You may need to set registration effective dates and nexus status manually from your own records. Contact our support team to walk through your situation. What date range should I sync? Sync from January 1st of the previous calendar year through today. Integrating in March 2026, for example, means syncing January 1, 2025 through March 2026. That gives nexus calculations a complete data set. Do I need to sync transactions for tax calculation only? In most cases, yes. Even when Kintsugi is not handling filing and remittance, tax calculation depends on nexus status, and Kintsugi derives nexus from your transaction data. The one exception is when you manage nexus and compliance entirely elsewhere and need Kintsugi only for rate lookup. ## When to Use Each Endpoint Knowing where each endpoint belongs in your workflow prevents wasted API calls and keeps your data consistent. Tax Estimation Endpoint ( POST /tax-estimations) Call this endpoint during checkout or billing, before payment is collected. Typical integration points: Shopping cart pages: When customers review their order before payment Checkout flows: After address entry, before payment processing Subscription billing: When calculating tax for recurring charges Quote generation: When quoting a price to a customer The estimation endpoint stores nothing, so you can call it as often as customers change their cart or address. To price the same cart again, send the same request again. Best practice: Call POST /tax-estimations once the customer has entered an address and before final payment processing. Addresses are validated as part of the estimate, and one that cannot be validated returns 400, so you find out before the customer pays. Transaction Sync Endpoint ( POST /transactions) Call this endpoint once a sale is complete and payment is confirmed. Typical integration points: Order confirmation: After payment succeeds and the order is finalized Invoice creation: When generating invoices for completed sales Daily batch jobs: Syncing from your order management system Webhook handlers: Processing order completion events from e-commerce platforms Transaction records should reflect real completed sales, not estimates or open carts. Send type: "SALE" to record a sale. Do not sync open carts: The create request has no status field, and a sale recorded through POST /transactions is stored as COMMITTED, which is the status that counts toward filed liability. Sync only after payment is confirmed. ## When to Use Each Endpoint POST /transactions answers 202 Accepted. The transaction is recorded immediately and tax is calculated afterwards, so the response starts with a processingStatus of QUEUED and tax totals of "0.00". ## Integration Setup Workflow Your setup sequence depends on your integration type, but the shape is consistent. Step 1: Create Product Records Every integration starts with product records. Products carry the tax classification that decides whether an item is taxable in a given jurisdiction. Create products before you calculate tax or sync transactions. See the Product & Customer Records guide for product creation workflows. Step 2: Create Customer Records (If Needed) Customer records are required only when you sell to exempt entities such as nonprofits, resellers, or government agencies. If you sell to ordinary consumers, skip this step and pass customer details inline on the transaction. See the Product & Customer Records guide for when and how to create customer records. Step 3: Historical Transaction Sync (L1, L2, or Tax Calculation) If you use transaction sync (L1 or L2) or tax calculation with Kintsugi-managed nexus, import historical transactions from the previous calendar year. This is a one-time bulk operation that sets your nexus tracking baseline. See the Syncing Transaction Records guide for bulk import strategy. Step 4: Real-Time Integration With setup complete, wire the right endpoints into your live workflows: L1 (transaction sync only): POST /transactions on order completion Tax calculation only: POST /tax-estimations in checkout, plus transaction sync for nexus L2 (both): POST /tax-estimations at checkout and POST /transactions after payment confirmation ## Common Integration Patterns Different business models call for different approaches. E-Commerce Platforms Most e-commerce platforms land on L2. Start with L1 to sync completed orders for compliance, then enable the tax engine to price tax during checkout and show customers an accurate total before they pay. A Level 2 checkout makes two Kintsugi calls: one to quote tax, one to record the sale. 1 Customer adds items to cart Your storefront, no Kintsugi call yet. 2 Customer enters shipping address Destination determines the rate. 3 Calculate tax Nothing is recorded. POST /tax-estimations Returns tax amount 4 Display total with tax Show the quoted amount before payment. 5 Process payment Declined? Return the customer to the cart. No transaction is recorded, so there is nothing to reverse in Kintsugi. 6 Record the transaction POST /transactions Only after payment succeeds 7 Order complete The sale now counts toward nexus and appears in filings. Subscription Billing Platforms Subscription platforms typically run L2: calculate tax when a subscription is created and at each renewal, then sync the transaction per billing cycle for compliance. Marketplace Platforms Marketplaces often price tax for sellers without owning seller compliance. Tax calculation only fits well here, with sellers handling their own transaction sync. Transaction data is still required wherever Kintsugi manages nexus. Accounting System Integrations Accounting integrations usually start at L1: sync invoices and completed sales for compliance tracking, with no real-time calculation. Enable the tax engine (L2) later if the need appears. ## Next Steps Once you have chosen your integration type: Set up authentication: Every request carries your key in the Api-Key header. When your key can reach more than one organization, add an Organization-Id, Connection-Id or Entity-Id header to choose one. See Creating and Managing API Keys for details. Create product records: Start with your catalog. See the Product & Customer Records guide. Plan your data sync: If you need transaction sync, plan the historical import. See the Syncing Transaction Records guide. Build your integration: Wire the endpoints into the workflows described above. For endpoint-level detail, see the API Reference. --- # 2. Product & Customer Records (2026-10-06) Create and manage product and customer records that power tax calculations and compliance tracking Source: https://docs.trykintsugi.com/docs/2026-10-06/api-guides/product-customer-records Product and customer records are the foundation of every Kintsugi integration. Products carry the tax classification that decides whether an item is taxable in a given jurisdiction. Customer records anchor exemptions to the buyers who hold them. This guide covers when to create each record, how to reference them, and how to verify they landed. ## Understanding Product Records A product record maps one of your catalog items to a Kintsugi tax classification. Each record holds: Your identifier for the item ( externalId) plus its name and description A tax classification ( productCategory and productSubcategory) A tax-exempt flag ( taxExempt) An approval status ( status) Transaction lines and tax estimates reference products by externalProductId. Kintsugi reads the matching product's classification to decide whether the item is taxable where your customer is. Create products first: Transaction lines reference products by externalProductId, so create your catalog before calling POST /transactions. A tax estimate line can instead name a productCategory and productSubcategory pair, which is priced without creating a product, but a pre-built catalog keeps classification consistent across every call. ## Creating Product Records Create products with POST /products. POST /products -H "Api-Key: ***" -H "Api-Version: 2026-07-21" { "externalId": "sku-1001", "name": "Blue T-Shirt", "productCategory": "Physical", "productSubcategory": "General Clothing", "taxExempt": false, "source": "API" } A new product answers 201. Creating is idempotent on externalId and source: sending the same pair again returns the existing product unchanged with 200 instead of creating a duplicate. Use PATCH /products/{product_id} to change it. Required Fields externalId: Your stable identifier for the product (for example, "sku-1001") name: Product name productCategory: Top-level tax category: Digital, Misc, Physical, or Services productSubcategory: Subcategory label within that category, such as General Clothing or B2B SaaS. An unrecognized category and subcategory pair returns 400 taxExempt: Whether tax calculation treats the product as exempt Optional Fields description: Product description status: Approval status ( APPROVED, PARTIALLY_APPROVED, or PENDING) source: Where the record originated, for example API. Defaults to OTHER sourceTaxExempt: The raw tax-exempt signal from your source system, stored for auditing. taxExempt is the flag tax calculation applies Pull the category list from the API: Supported categories and subcategories are returned by List the product category catalog. Its category and each subcategory label are the exact values productCategory and productSubcategory accept. Read from that endpoint rather than hardcoding values, so your mapping stays valid as the taxonomy grows. What if I have thousands of products? ## Creating Product Records Create them in batches. POST /products takes one product per request, so send them in chunks and pause between chunks. Because creating is idempotent on externalId and source, re-sending a product that already landed returns it with 200 rather than a duplicate. Products never expire, so you can build the catalog well ahead of your first transaction. Do I need to update products if tax rules change? No. Kintsugi tracks jurisdiction rule changes for you, and product records stay as they are. Update a product only when your own classification changes, for example when an item moves from one category or subcategory to another. Can I delete products? Yes. DELETE /products/{product_id} archives a product: it disappears from GET /products and every read returns 404. The identity stays taken, so creating a product again with the same externalId and source, or a transaction that references the same externalId, restores it. A restored product returns to PENDING and is not used in tax calculation until it is approved again. ## Verifying Product Records Confirm your catalog with GET /products. The endpoint is cursor-paginated ( limit up to 100, default 50, and the cursor from a prior response's nextCursor or previousCursor) and supports: search over product id, externalId, name, and description. The id and externalId must match exactly; name and description match a case-insensitive substring productCategory and productSubcategory to check classification coverage status (comma-separated) to surface anything still PENDING source (comma-separated) to scope results, and orderBy with order to sort them To fetch one product directly, use GET /products/{product_id} with the Kintsugi product ID returned at creation. Look up by your own ID: search matches externalId exactly, so GET /products?search=sku-1001 finds the product you created as sku-1001. Saving the id from your create response still gives you the most direct lookup. Product Creation Workflow Products carry the tax category that drives every rate lookup. Create them before the first transaction. 1 Prepare and validate the payload Five fields are required before you send anything. externalId name productCategory productSubcategory taxExempt Pull the category and subcategory values from GET /products/categories rather than hardcoding them. 2 Create the product POST /products Returns the product id Non-2xx? See error handling below. 3 Verify it exists GET /products Optional, recommended 4 Product is ready for tax calculations Reference it by its externalId, as externalProductId, in estimates and transactions. ## Understanding Customer Records A customer record identifies a buyer and gives exemptions something to attach to. Create customer records when you sell to: Nonprofit organizations Government agencies Resellers holding valid exemption certificates Any other exempt entity Exemptions themselves are separate records created against a customer through Create an exemption. When a tax estimate's customer.externalId matches a customer Kintsugi holds, that customer's exemptions and tax registrations are applied to the estimate. When you don't need customer records: Selling only to ordinary consumers? Skip customer creation and pass the buyer's details inline on the transaction's customer object. ## Creating Customer Records Create customers with POST /customers. Every field is optional, so send everything you have; in practice, exemption matching and address-based tax work depend on the fields below. POST /customers -H "Api-Key: ***" -H "Api-Version: 2026-07-21" { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com", "source": "API", "street1": "123 Main St", "street2": "Suite 400", "city": "San Francisco", "state": "CA", "postalCode": "94105", "country": "US" } A new customer answers 201 and is always ACTIVE. Creating is idempotent on externalId and source, and on connectionId when you send one: sending the same values again returns the existing customer unchanged with 200. Fields to Send externalId: Your stable identifier for the customer (for example, "cust-1001") name: Customer name email: Contact email address Address fields: street1, street2, city, county, state, postalCode, and country (ISO 3166-1 alpha-2) Other Optional Fields companyName: Registered or legal business name, when it differs from name phone: Contact phone number source: Where the record originated. Defaults to OTHER connectionId: The connection to attribute the customer to externalFriendlyId: A human-facing identifier from your source system taxRegistrations: The customer's tax registrations, each with a countryCode, taxType, and taxId Customer Addresses A customer record carries one address, written as flat fields on the record itself rather than as a list. That address identifies the customer; it does not decide the tax jurisdiction on its own. ## Creating Customer Records Jurisdiction comes from the addresses on the transaction or estimate, where each entry has a type of SHIP_TO, BILL_TO, SHIP_FROM, or BILL_FROM. Tax is sourced to the SHIP_TO address when one is supplied, and to BILL_TO otherwise. Adding Exemptions With the customer created, attach the exemption using POST /exemptions. That request needs: exemptionType: What the exemption applies to: customer, wholesale, transaction, or reverse_charge startDate: First day the exemption is in force ( YYYY-MM-DD) customerId: The Kintsugi customer ID from your create response Add endDate, countryCode, jurisdiction, reseller, fein, salesTaxId, and transactionId where they apply. status defaults to ACTIVE, the only status tax calculation applies. Upload the certificate itself, a PDF of at most 10 MB, with POST /exemptions/{exemption_id}/certificates. ## Verifying Customer Records Confirm your customers with GET /customers. The endpoint is cursor-paginated ( limit up to 100, default 50, plus cursor) and supports: search over customer id, name, email, externalId, and externalFriendlyId. The id, externalId, and externalFriendlyId must match exactly; name and email match a case-insensitive substring country and state (comma-separated) to scope results by geography source and connectionId (comma-separated) to filter, and sort with order to sort For an exact lookup by your own identifier, use GET /customers?search=. With the Kintsugi customer ID, use GET /customers/{customer_id}. Customer Creation Workflow A customer record is only required when exemptions are involved. Everyone else can be passed inline. Q Does this customer hold an exemption? NO Skip the customer record Pass customer data inline on the transaction The address on the transaction is enough to source the sale. YES Create the record so exemptions can attach to it 1 Prepare and validate the payload Every field is optional, so send everything you have. Exemption matching and address-based tax depend on these. externalId name email Plus the address: street1, city, state, postalCode and country. Run it through address validation first, since a bad address means a wrong rate. 2 Create the customer POST /customers Returns the customer id Non-2xx? See error handling below. 3 Attach the exemption Send the customer id as customerId. POST /exemptions Needs the customer id Then upload the certificate itself to POST /exemptions/{exemption_id}/certificates. 4 Verify it exists GET /customers Optional, recommended 5 Customer is ready Reference the customer by externalId on tax estimates and transactions. ## Using Products and Customers in Transactions With records in place, reference them from your tax estimates and transactions. Referencing Products Each transaction line points at a product through externalProductId: { "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "quantity": "2", "amount": "100.00" } ] } On a tax estimate the lines live in transactionItems and take the same externalProductId. Each line on a transaction response reports, as productId, the Kintsugi product it resolved to when one was matched. Referencing Customers Transactions and estimates carry the buyer on a customer object. Send your externalId there: { "customer": { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com" } } On a tax estimate, when the externalId matches a customer on file, Kintsugi applies that customer's exemptions and tax registrations. On a transaction, omit customer entirely for a sale with no customer identity, such as a marketplace or point-of-sale sale: the transaction is attributed to your organization's shared unattributed-sales customer. ## Updating Product and Customer Records Update with PATCH /products/{product_id} and PATCH /customers/{customer_id}. Both are partial updates: only the fields you send change. Typical cases: Products: Reclassifying category or subcategory, changing the taxExempt flag, revising name or description Customers: Correcting an address, updating contact details, adding tax registrations Recategorizing sets the exemption for you: On a product update, taxExempt is honored only when the category is unchanged. When you recategorize, the exemption is derived from the new category and the taxExempt you send is ignored. source is not editable, and reusing another product's externalId returns 409. On a customer, sending any address field resets addressStatus to UNVERIFIED, and the new address is validated the next time the customer is processed. taxRegistrations upserts each entry on its countryCode and taxType pair and cannot remove one. To retire a customer, DELETE /customers/{customer_id} archives it; creating a customer again with the same externalId and source restores it with its transactions and exemptions attached. When to update versus create new: If an item's tax treatment fundamentally changes, for example moving from physical goods to a digital download, create a new product under a new externalId instead of editing the old one. That keeps a clean audit trail of when the classification changed. ## Best Practices Product Management Build the catalog first: Have products in place before you wire up tax calculation or transaction sync Read categories from the API: Source values from List the product category catalog instead of hardcoding them Use consistent external IDs: Pick one convention, such as always the SKU, and hold it across every system Batch creation: Send products in chunks rather than all at once Verify before you rely on them: Confirm products exist before referencing them in transactions Customer Management Create records where exemptions live: Ordinary consumers can travel inline on the transaction Validate addresses: Run addresses through address validation before you save them Store Kintsugi customer IDs: You need the id to attach exemptions and for direct lookups Handle exemptions as a second step: Create the customer, then attach exemptions through Create an exemption ## Error Handling Same policy for products and customers. Every error comes back in one envelope, { "code", "message", "requestId", "errors": [...] }, where errors holds one entry per request field that failed validation, each with a field, code, and message. Read it, then decide whether the failure is worth retrying. RETRYABLE 5xx · 429 Back off, then re-send Send the identical payload. Creating a product or customer is idempotent on externalId and source, so a retry of a request that already landed returns the existing record with 200 rather than a duplicate. NOT RETRYABLE Other 4xx Fix the data, then re-send The errors array names the offending field. Correct it, then re-send. Retrying unchanged will fail the same way. Cap retries. Three attempts is plenty. After that, log the payload, the response, and its requestId, and surface it for a human rather than looping. Common Failures What actually goes wrong when creating products and customers: Invalid category or subcategory: An unrecognized pair returns 400. Match values to List the product category catalog Missing required fields: Products need externalId, name, productCategory, productSubcategory, and taxExempt Duplicate externalId on update: Changing a product's externalId to one another product uses returns 409 Invalid address: Validate addresses before saving them Missing or invalid API key: Every request needs a valid Api-Key header, or it returns 401 For the full status-code reference and retry strategies, see the Error Handling guide. ## Integration Checklist Before you wire up tax calculation or transaction sync: [ ] Created product records for every item in your catalog [ ] Verified products exist and carry the classification you expect [ ] Created customer records for exempt entities (if applicable) [ ] Attached exemptions to those customers and uploaded certificates (if applicable) [ ] Tested product lookup in a sample tax estimate request [ ] Tested customer lookup in a sample tax estimate request ## Next Steps With products and customers in place: Start calculating tax: Reference products in POST /tax-estimations requests. See the Sales Tax Calculations guide. Sync transactions: Reference products and customers in POST /transactions requests. See the Syncing Transaction Records guide. Handle updates: Set up workflows to push catalog and customer changes through to Kintsugi. For endpoint-level detail, see: Create a product List products List the product category catalog Create a customer List customers Create an exemption --- # 3. Syncing Transaction Records (2026-10-06) Sync completed sales transactions to Kintsugi for compliance tracking and nexus determination Source: https://docs.trykintsugi.com/docs/2026-10-06/api-guides/syncing-transaction-records Transaction sync (also called Level 1 or L1) creates the permanent record of your completed sales in Kintsugi. Those records drive nexus tracking, compliance reporting, and filing preparation. Every Kintsugi integration rests on them, whether you run L1 only, tax calculation only, or L2. This guide covers when to sync, how to shape the payload, and how to run a clean bulk import. ## Understanding Transaction Sync Each transaction represents one completed sale, carrying: Transaction details: date, type, amount, currency Line items that reference your products Customer details and addresses Tax amounts you already collected, when tax was charged at checkout Kintsugi uses those records to: Determine economic nexus by tracking sales volume and transaction counts by jurisdiction Prepare filings by aggregating transactions per jurisdiction Maintain an audit trail for compliance Track refunds and credit notes against original sales Transaction sync (L1) is the foundation: POST /transactions records sales; tax on them is calculated asynchronously afterwards. With the tax engine (L2) enabled, Kintsugi prices tax at checkout through POST /tax-estimations and you still sync the completed transaction afterward. Tax calculation without transaction sync is only viable when nexus and compliance are managed elsewhere. See Planning an Integration. ## When to Sync Transactions Sync once the sale is complete and payment is confirmed. The cadence is yours to choose. Real-Time Sync Sync immediately after order completion when you have: High-volume e-commerce A requirement for immediate compliance visibility Real-time reporting needs Real-time sync keeps your nexus status and compliance data current to the minute. Batch Sync Sync in batches when you have: An accounting system integration Periodic order exports A daily or weekly operational rhythm Batching suits systems that already process orders in groups. Batch cadence: Sync at least daily. Economic nexus thresholds are evaluated over a rolling 12-month period or a calendar year depending on the state, so a daily rhythm keeps your tracking gap-free. ## Transaction Statuses Status decides whether a transaction affects your compliance position. A transaction's status reads back as one of PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, or INVALID. COMMITTED Counts toward filed liability. A sale you record through POST /transactions is stored with this status. PENDING May still change, and does not count toward filed liability. The create and update requests have no status field, so the Tenanted API does not let you record a sale as pending or move it between statuses yourself. Refunds are tracked separately: A sale that has been credited keeps its own status, and its refund position is held apart from it. To find refunded sales, filter GET /transactions with refundStatus=FULLY_REFUNDED,PARTIALLY_REFUNDED. See Handling Refund Transactions for how credit notes drive it. ## Choosing a Sync Pattern Because a sale recorded through the API is stored as COMMITTED and counts at once, sync it after payment clears. The payment gate comes first: nothing is sent until you know the order is real. 1 Order placed, payment processes Entirely in your system. No Kintsugi call yet. DECLINED → Stop. Don't sync. There is no transaction in Kintsugi, so there is nothing to reverse. 2 Assemble and check the payload externalId date currency addresses items customer Every product should already exist as a product record, and every address should validate. 3 Send the transaction POST /transactions type: SALE Answers 202 Accepted with the recorded transaction. 4 Synced and counting toward nexus Tax is calculated asynchronously. Read the transaction back and watch processingStatus: PROCESSED means tax calculation has completed. GET /transactions/{transaction_id} answers 404 until processing completes, so poll it rather than treating the first 404 as a failure. No create-pending-then-commit pattern: The v1 API lets you record a sale as PENDING and commit or cancel it later. The Tenanted API has no status on create or update, so that pattern is not available here. Hold the sale in your own system until the payment outcome is known. ## Creating Transactions Create transactions with POST /transactions, one transaction per request. POST /transactions -H "Api-Key: ***" -H "Api-Version: 2026-07-21" { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "description": "Order 2001", "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "country": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } Required Fields externalId: Your stable identifier for the transaction (for example, "order-2001") date: When the transaction occurred, as an RFC 3339 timestamp. It drives which filing period the sale lands in, so send the real transaction time, not the time of the call currency: ISO 4217 currency code of every amount, for example USD Recommended Fields type: Transaction type. SALE records a sale and is the default totalAmount: Defaults to "0.00", so send the real total addresses: Jurisdiction is resolved from these, so an incomplete address means tax cannot be calculated accurately items: The line items sold customer: The buyer, with externalId, name, email, and companyName. Omit it for a sale with no customer identity, such as a marketplace or point-of-sale sale source: Where the sale originated, for example API. Defaults to OTHER description: A human-readable label that pays for itself when reconciling ## Creating Transactions marketplace: true for reseller or marketplace orders where tax was remitted by someone else. Tax liability is excluded. Whether gross sales count toward a state's nexus threshold depends on the state, as each nexus period's includeMarketplaceTransactions shows Your organization comes from the credential: The request body carries no organization field. When your key can reach more than one organization, choose one with an Organization-Id, Connection-Id, or Entity-Id header, and let the body describe the sale. Money fields are decimal strings, such as "100.00". Re-sending an externalId that already exists does not create a second transaction. Transaction Items Each line item points at a product: externalProductId (required): The product's identifier in your system date (required): Date and time of the line, normally matching the transaction date externalId: Your identifier for the line item. Send it on every line: a credit note can only reverse a line by its externalId quantity: Defaults to "1" amount: Line amount before tax. Defaults to "0.00", so send the real figure product and description: Product name and line description taxAmountImported: Tax you already collected on this line, if any Addresses Every address entry needs a type of SHIP_TO, BILL_TO, SHIP_FROM, or BILL_FROM, plus the address itself: street1, street2, city, county, state, postalCode, and country (ISO 3166-1 alpha-2). Tax jurisdiction usually follows the SHIP_TO address, or BILL_TO when there is no ship-to. ## Creating Transactions Transactions are processed asynchronously: POST /transactions returns 202 Accepted with the recorded transaction, a processingStatus of QUEUED, and tax totals of "0.00". totalTaxAmountCalculated and the per-line taxItems populate shortly afterwards. The returned id is not fetchable straight away either: GET /transactions/{transaction_id} answers 404 until processing completes, so poll it rather than treating the first 404 as a failure. ## Historical Transaction Sync Transaction sync integrations start with a historical import covering the previous full calendar year through today. This one-time operation sets your nexus tracking baseline. Historical Data Requirements Cover: Start date: January 1st of the previous calendar year End date: Today, or your integration start date Scope: All completed sales in that window What if I don't have complete historical data? Send what you have. Kintsugi tracks nexus forward from the data it receives. You may need to set registration effective dates manually where records are missing. Contact support and we will work through it with you. Should I sync refunded transactions? Yes. Sync the sale, then record each refund as a credit note against it. The result is a complete, defensible audit trail. See Handling Refund Transactions. How do I handle large historical imports? Chunk by date range and send transactions in groups, pausing between chunks. Because processing is asynchronous, you can move large volumes without long-running requests. If you would rather not build an importer, CSV file upload covers the same ground. Bulk Import Strategy For large historical imports: Chunk by date range: Work month by month or week by week Batch your requests: The endpoint takes one transaction per call, so send them in groups and pause between groups Handle errors deliberately: Log failures with their requestId, fix the data, replay the batch Verify completion: Reconcile with GET /transactions by date range against your source-of-truth counts Order matters: Import oldest first. Nexus is evaluated against transaction dates, and a chronological import keeps threshold crossings accurate as they are calculated. ## Verifying Transactions Read transactions back with GET /transactions. The endpoint is cursor-paginated ( limit up to 100, default 50, plus cursor) and supports: startDate and endDate ( YYYY-MM-DD) for date ranges status and processingStatus (comma-separated) to separate committed, pending, and still-processing records search for a free-text search over transaction id, externalId, externalFriendlyId, description, and customer name type, country, state, marketplace, exempt, source, and filingId to narrow further sort and order to sort. The default is date, descending, so newest first For a direct lookup, use GET /transactions/{transaction_id} with the Kintsugi transaction ID. The Tenanted API has no lookup by externalId; use search instead. ## Updating Transactions Update with PUT /transactions/{transaction_id}. It is a replace: send externalId, date, and currency on every call, and the scalar fields and the customer are overwritten with what you send. Typical cases: Address corrections: Addresses are replaced per type, so a SHIP_TO you send replaces the stored ship-to and a type you omit is left as it was Amount adjustments: Correcting totals or line items. Lines are matched by externalId: a new externalId is added, and a stored line whose externalId you do not send is removed The transaction's type cannot be changed, and tax is recalculated asynchronously after the update. Credit notes have their own update, PATCH /transactions/{transaction_id}. Filed transactions lock: A locked or already-filed transaction answers 409 and can no longer be updated. Make corrections before the filing period closes. To remove a sale entirely, Archive a transaction. Archiving is one-way: the transaction disappears from every read, cannot be restored, and stops counting toward nexus. A locked or already-filed transaction cannot be archived. ## Best Practices Data Quality Use consistent external IDs: One convention across every system, on the transaction and on every line Validate before syncing: Confirm products exist and addresses are valid first Send complete data: Fields with defaults, especially totalAmount and item amount, will silently post as zero if you omit them Get timestamps right: Send the real transaction time on date, as an RFC 3339 timestamp Sync Timing Sync after payment confirmation: A synced sale is committed and counts at once Sync in chronological order: Oldest first, especially on historical imports Store Kintsugi transaction IDs: You need the id for updates, credit notes, and direct lookups Monitor the pipeline: Track both request success and processingStatus on the records you create Error Handling Common failures when syncing transactions: Invalid address: Validate addresses before syncing Missing required fields: externalId, date, and currency are required. The error's errors array names each field that failed Locked transaction: Updating or archiving a filed transaction returns 409 Missing or invalid API key: Every request needs a valid Api-Key header, or it returns 401 See the Error Handling guide for detailed strategies. ## Integration Patterns E-Commerce Platforms E-commerce platforms typically sync the moment an order completes: Order is placed and payment confirmed Create the transaction with type: "SALE" Include every line item with its product reference and line externalId Include the shipping address so the jurisdiction resolves correctly Subscription Platforms Subscription platforms sync per billing cycle: The subscription invoice is generated Create the transaction once the invoice is paid Reference the subscription product and the customer Include the billing address Accounting Systems Accounting systems sync in batches: Export completed invoices and sales Create transactions with type: "SALE" Process in date order, oldest first Retry failures after correcting the underlying data ## Next Steps With transaction sync running: Handle refunds: Record credit notes against original sales. See the Handling Refund Transactions guide. Query transactions: Use the GET endpoints for reporting and reconciliation. See the List transactions API reference. Monitor sync health: Watch request success rates and processingStatus so failures surface early. For endpoint-level detail, see: Create a transaction List transactions Get a transaction by id Update a transaction --- # 4. Handling Refund Transactions (2026-10-06) Create credit notes and refund records that properly track refunds for compliance and filing preparation Source: https://docs.trykintsugi.com/docs/2026-10-06/api-guides/handling-refund-transactions Refunds change what you owe, so they need to reach Kintsugi as deliberately as the sales they reverse. A credit note records a refund against the original transaction, keeping your filings anchored to net sales rather than gross. This guide covers when to create credit notes, how to shape them, and how full and partial refunds behave. ## Understanding Credit Notes A credit note in Kintsugi represents a refund, return, or adjustment against an original sale. Each credit note: Is created against the original transaction, which you name with originalTransactionId Carries the amount being credited on totalAmount and on each line item Updates the original transaction's refund status Offsets the original sale in compliance calculations The outcome is filings that reflect what you actually kept. Credit notes are transactions: In the Tenanted API there is no separate credit note endpoint. Create one with POST /transactions, setting type to FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE and sending originalTransactionId. Kintsugi derives the stored type from the amount credited, so it can differ from the one you send. ## When to Create Credit Notes Create a credit note whenever you refund, accept a return, or adjust a completed sale: Product returns: The customer sends items back Service cancellations: The customer cancels and is refunded Billing adjustments: You correct an overcharge or an error Partial refunds: You refund specific line items rather than the whole order Which sales can be credited: The original must be a sale whose status is PENDING, COMMITTED, or PARTIALLY_REFUNDED. A transaction that is not a sale, or a sale in any other state, such as CANCELLED, is rejected with 400. Reversing a transaction you do not own answers 404, the same as one that does not exist. ## Creating Credit Notes Create credit notes with POST /transactions. originalTransactionId is the original transaction's Kintsugi transaction ID, not your externalId. The credit note inherits the original transaction's customer, addresses, and source, so you send only the lines to credit. A credit note created through the API takes effect immediately: it is stored as COMMITTED, and the original sale's refund status is reconciled in the same request. Like any create on this endpoint, it answers 202 Accepted. Required Fields type: FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE originalTransactionId: The Kintsugi ID of the sale being reversed externalId: Your unique identifier for the credit note (for example, "cn-1") date: Credit note date, normally the refund date, as an RFC 3339 timestamp currency: ISO 4217 currency code, for example USD items: The line items being credited. At least one is required Optional Fields totalAmount: The amount being credited. Defaults to "0.00", so send the real figure description: The reason for the refund, which is worth sending on every credit note marketplace: Inherited from the original sale when you omit it Credit Note Line Items Each item reverses one line of the original sale and needs: externalId (required): The externalId of the original line being reversed. Each original line can appear only once per credit note externalProductId (required): The same product identifier used on the original line date (required): Item date taxableAmount (required): The portion being credited that is subject to tax, so a partial reversal credits the taxable amount actually being reversed quantity: Units being credited amount: Value being credited for that line ## Creating Credit Notes The original lines need external IDs: A credit note can only reverse a line by its externalId. A line that does not match a line on the original sale is rejected with 400, so send externalId on every line when you sync the sale. Either sign works: Send totalAmount and item amounts positive or negative as you prefer. Kintsugi stores credit note amounts as negative values, so the stored record is consistent either way. Quantities stay positive. Re-sending the same credit note externalId against the same original sale returns the stored credit note rather than an error, so a retried request is safe. The same externalId against a different original sale returns 409. Credit Note Workflow You never edit the original sale. You attach a credit note to it, and Kintsugi adjusts your liability from there. 1 Find the original transaction GET /transactions?search= Look it up by your own id originalTransactionId takes Kintsugi's transaction id, not your externalId, so you need this unless you stored the id when you synced the sale. 2 Check the sale can be credited It must be a sale whose status is PENDING, COMMITTED, or PARTIALLY_REFUNDED. REJECTED → A transaction that is not a sale, or a sale in any other state such as CANCELLED, comes back 400. One you do not own answers 404, the same as one that does not exist. 3 Build the credit note Match each line you are crediting to a line on the original sale by externalId, give each a taxableAmount, then total them. CHECK Two independent caps apply, both against the remaining balance: the total against the sale's totalAmount plus its tax, and each line against its original line. An over-refund is rejected with 400, not trimmed to fit. 4 Create the credit note ## Creating Credit Notes type originalTransactionId externalId date currency items POST /transactions Answers 202 Accepted Set type to FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE. Non-2xx? Back off and retry on 5xx and 429; fix the payload on other 4xx. See Error Handling. 5 Refund recorded The credit note is stored as COMMITTED, the original sale's refund status is reconciled in the same request, and the credit offsets the sale in compliance calculations. ## Full Versus Partial Refunds Kintsugi reads the amounts and classifies the refund for you. Full Refunds When the credit note covers the full original amount, Kintsugi records: Credit note type: "FULL_CREDIT_NOTE" Original transaction refund status FULLY_REFUNDED The original sale is fully offset for compliance purposes. The two values are derived differently: When a credit note is created, its type is decided by comparing that note's totalAmount against the sale's. The sale's refund status is cumulative, comparing the total of every committed credit note against the sale's totalAmount. On a single full refund they agree; across several partial refunds they can differ, so use the refund status when you need the sale's overall position. Partial Refunds When the credit note covers less than the original amount, Kintsugi records: Credit note type: "PARTIAL_CREDIT_NOTE" Original transaction refund status PARTIALLY_REFUNDED The sale is reduced, not erased. You can add further partial credit notes against the same transaction while creditable balance remains. Two caps apply, both against the remaining balance: Kintsugi checks the credit note total against what is still creditable on the sale, and separately checks each line against what is still creditable on the matching original line. Either one over is a 400, so an over-refund is rejected rather than trimmed to fit. The transaction-level cap is the sale's totalAmount plus its tax, minus everything already credited by committed credit notes. The tax counted is the sale's imported tax when it has any, and the tax Kintsugi calculated otherwise. ## Matching the Original Transaction Credit note line items should mirror the sale they reverse: Use the same line externalId and externalProductId values. A product that is not on the original transaction is rejected with 400 Keep credited quantities at or below the original quantities Keep credited amounts at or below the original amounts That discipline gives you clean reporting on which products were returned, and an audit trail that holds up under review. ## Credit Note Statuses Credit notes use these status values: COMMITTED: Refund complete and included in compliance calculations. Every credit note created through the API starts here PENDING: Refund not yet finalized. A pending credit note does not count toward the credited total CANCELLED: Credit note reversed without being deleted ## Updating Credit Notes Update with PATCH /transactions/{transaction_id}, where transaction_id is the credit note's own Kintsugi ID. The original sale is taken from the credit note itself, so you do not send it. This is a true partial update: externalId, date, status, currency, totalAmount, description, marketplace, and items are all optional, and any you omit keep their stored values. Typical cases: Reversing a refund: Send status: "CANCELLED" to reverse the credit note without deleting it Amount corrections: Fixing an incorrect refund figure Item adjustments: Revising which lines were credited. Each item must carry the externalId of the original line it reverses, exactly as on create status does not default to COMMITTED on an update; omitted, it stays what it is. Calling this on a transaction that is not a credit note returns 400, and so does updating a credit note that is already CANCELLED. PUT /transactions/{transaction_id} amends ordinary transactions and does not accept a credit note. Filed records lock: A locked or already-filed credit note answers 409 and can no longer be updated. Make corrections before the filing period closes. ## Best Practices Creating Credit Notes Mirror the original: Same line IDs, same products, amounts that reconcile Validate before you post: Check the remaining creditable balance so the request is not rejected Use descriptive external IDs: Tie the credit note back to the sale, for example CN-\{original_id\} Always send a description: The refund reason is the first thing anyone asks about months later Send a taxable amount on every line: It is required, and it is what keeps a partial refund's tax correct Finding Original Transactions Store Kintsugi transaction IDs: originalTransactionId needs the Kintsugi ID, so save it when you create the transaction Fall back to search: Without the Kintsugi ID, find the sale with GET /transactions?search= Handle not-found cleanly: The original transaction must exist before a credit note can reference it Error Handling Common failures when creating credit notes: Original transaction not found: Confirm you are passing the Kintsugi transaction ID, not your externalId. A missing or foreign transaction returns 404 Amount exceeds creditable balance: Subtract already-committed credit notes from the sale total plus its tax before you post, and check the line-level balances too Sale cannot be credited: The original must be a sale whose status is PENDING, COMMITTED, or PARTIALLY_REFUNDED Line does not match the original: Every item needs an externalId matching a line on the sale, listed once, with a taxableAmount Product mismatch: Reference the same products as the original line items Missing originalTransactionId: Required whenever type is a credit-note type, and rejected on a SALE See the Error Handling guide for detailed strategies. ## Refund Scenarios Single Item Return A customer returns one item from a multi-item order: Find the original transaction Create a credit note containing only the returned line item Credit that item's share of the order Kintsugi marks the original transaction PARTIALLY_REFUNDED Full Order Refund The entire order is refunded: Find the original transaction Create a credit note containing every line item Credit the full original amount Kintsugi marks the original transaction FULLY_REFUNDED Multiple Partial Refunds Refunds arrive over time: Create a credit note for the first refund Add further credit notes as later refunds are issued Kintsugi tracks the cumulative credited total The original stays PARTIALLY_REFUNDED until the credited total reaches the original amount ## Refund Status Tracking Credit notes are cumulative. Each one reduces the remaining balance, and the refund status follows the total. The worked example below assumes a sale with no tax; when the sale carries tax, the creditable balance includes it. Worked example Bar shows the amount still refundable Original transaction $100.00 Committed, nothing credited yet $100.00 remaining CREDIT NOTE 1 Partial refund −$30.00 PARTIALLY_REFUNDED $70.00 remaining CREDIT NOTE 2 Refunds the rest −$70.00 FULLY_REFUNDED $0.00 remaining Two credit notes of $70.00 against a $100.00 sale is rejected, not clamped: the second comes back 400 and nothing is written. Check the remaining balance before every credit note, not just the first. Refund Status on the Original Kintsugi derives the sale's refund status from the credit notes committed against it. Until one is committed the sale has no refund status, and only committed credit notes count: a PENDING credit note neither consumes the balance nor moves the status. PARTIALLY_REFUNDED Committed credit notes total less than the sale's totalAmount. The sale can carry further credit notes while creditable balance remains. FULLY_REFUNDED Committed credit notes reach the sale's totalAmount. Cancelling a credit note recomputes the sale's refund status from the committed credit notes that remain. Reading the refund status: The transaction response does not carry a refund status field. Find refunded sales by filtering GET /transactions with refundStatus=FULLY_REFUNDED,PARTIALLY_REFUNDED, and list the credit notes against one sale with List related transactions. The Tenanted API does not let you set a refund status directly. ## Next Steps With refund handling in place: Verify credit notes: Read them back with GET /transactions/{transaction_id}, list the credit notes against a sale with GET /transactions/{transaction_id}/related, and filter the transaction list with type=CREDIT_NOTE to review credit notes on their own. See the List transactions API reference. Monitor refund status: Filter on refundStatus across your transactions so compliance figures stay accurate. Plan for edge cases: Decide up front how you handle reversed refunds and refunds that span filing periods. For endpoint-level detail, see: Create a transaction Update a credit note Get a transaction by id --- # 5. Sales Tax Calculations (2026-10-06) Calculate accurate sales tax rates using Kintsugi's tax estimation endpoint in your checkout and billing flows Source: https://docs.trykintsugi.com/docs/2026-10-06/api-guides/sales-tax-calculations The tax estimation endpoint ( POST /tax-estimations) prices sales tax before you take payment. It is the core of the Level 2 (L2) tax engine, enabled once transaction sync (L1) is in place. Rates reflect your registrations, your product taxability, your customer's exemptions, and the address you are shipping to. This guide covers when to call it, how to shape the request, and how to use what comes back. ## Understanding Tax Estimates A tax estimate is a real-time calculation with no record behind it. Each estimate: Prices tax against your current registrations Applies the taxability rules for each product Honors customer exemptions Resolves rates for the destination jurisdiction Returns a per-line-item tax breakdown Nothing is stored and an estimate cannot be retrieved afterwards, so you can call the endpoint as often as customers change their cart or their address. To price the same cart again, send the same request again. Estimates do not sync transactions: POST /tax-estimations calculates tax; it does not record a sale. For full compliance (L2), sync the transaction separately through POST /transactions once payment is confirmed. Kintsugi determines nexus from those synced transactions, which is what makes accurate calculation possible in the first place, even when Kintsugi is not handling your filing and remittance. ## When to Calculate Tax Calculate during checkout or billing, after address entry and before payment processing. Common integration points: Shopping cart pages: When customers review their order Checkout flows: Once the shipping address is entered Subscription billing: When pricing a recurring charge Quote generation: When quoting a total to a customer Validate the address first: Run addresses through address validation before calculating. The estimate validates addresses too, and one that cannot be validated returns 400, so checking early lets you correct it while the customer is still on the page. ## Tax Estimate Request Structure An estimate request mirrors the shape of a transaction sync request, with its lines in transactionItems. POST /tax-estimations -H "Api-Key: ***" -H "Api-Version: 2026-07-21" { "externalId": "txn-1001", "date": "2026-07-28T12:00:00Z", "currency": "USD", "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "country": "US" } ], "transactionItems": [ { "externalId": "item-1", "externalProductId": "sku-1001", "quantity": "2", "amount": "100.00" } ] } The estimate is computed for exactly one organization. If your key can reach more than one, send an Organization-Id, Connection-Id, or Entity-Id header to choose it; without one, the request is rejected with 400. Required Fields externalId: Your identifier for the transaction being priced, echoed on the response date: When the transaction takes place. The rates in force on this date are the ones applied currency: ISO 4217 currency code, for example USD addresses: At least a SHIP_TO or BILL_TO address transactionItems: The line items to price. At least one Optional Fields customer: The buyer. Send externalId to match a customer on file and pick up their exemptions and tax registrations. Send null, or leave it out, when you have no buyer to attribute the sale to simulateActiveRegistration: Set true to price the transaction as though you were registered in the destination jurisdiction. Defaults to false Transaction Items Each line item requires: externalId: Your identifier for the line, returned on the matching response line so you can attribute each tax amount amount: Total for the line after discounts, as a decimal string And should carry: externalProductId: The product to price, one you have already created ## Tax Estimate Request Structure quantity: Defaults to "1" exempt: Set true to treat this specific line as exempt regardless of the rules. Defaults to false date: Only when the line's date differs from the transaction date. Leave it out to use the transaction date, which is almost always correct Classifying an item inline: Instead of an externalProductId, a line can name a productCategory and productSubcategory pair, optionally with productName and productDescription. The line is priced under that classification without creating a product. Send one or the other, not both, and note that an unrecognized pair returns 400. Pre-built catalogs keep classification consistent, so treat inline classification as a fallback rather than the default path. An externalProductId is unique only within a connection. When the same ID exists in more than one of your connections, send a Connection-Id header to price against that connection's product; without one, the ambiguous ID returns 400. Addresses Every address entry needs a type of SHIP_TO, BILL_TO, SHIP_FROM, or BILL_FROM, plus street1, street2, city, county, state, postalCode, and country (ISO 3166-1 alpha-2). A single fullAddress string can stand in for the structured fields, and isUnincorporated: true marks an address outside any city limit so city-level rates are not applied. Tax is sourced to the SHIP_TO address when one is supplied, and to BILL_TO otherwise. Addresses are validated as part of the estimate. An address that cannot be validated returns 400, one in a country Kintsugi does not cover returns 422, and an address-validation outage returns 503. ## Tax Estimate Response The response echoes your request and adds the calculation. At the top level: totalTaxAmount: Total tax due on the transaction taxableAmount: Total across all lines that tax was charged on taxRate: Combined effective rate across the transaction, as a fraction of the taxable amount hasActiveRegistration: Whether an active registration covers the destination jurisdiction addresses: The addresses as validated, each with a status. VERIFIED and PARTIALLY_VERIFIED are the only statuses an estimate is priced from On each entry in transactionItems: taxAmount: Tax due on that line taxableAmount: The portion of the line that tax was charged on taxRate: Combined rate applied to the line exempt and exemptReason: Whether the line was exempt, and why productCode, productCategory, and productSubcategory: The tax code the line was priced under taxItems: The tax applied per jurisdiction, each with a name, rate, amount, exempt flag, and exemptReason Amounts come back as strings: Monetary values and rates are returned as decimal strings, with amounts at 2 places and rates at 9, for example "8.25" and "0.082500000". Parse them with a decimal-safe type rather than a float so cents do not drift. Using Tax Amounts Take the figures from the response to: Show tax to customers during checkout Calculate the final total Carry tax amounts into the transaction you sync later Sanity-check the calculation before you charge Keep the estimate: Store the response so the transaction you sync afterward carries the same tax amounts the customer saw. Send each line's charged tax on that line's taxAmountImported when you call POST /transactions. Your records and your receipts then agree. ## Tax Calculation Workflow The Three Calls Each one gates the next. A bad address gives a wrong rate; an unrecorded sale never reaches your filings. CALL 1 Validate the address Destination decides the rate, down to the local jurisdiction. Recommended rather than required, and it fills in fields such as county when it can. / addresses/ validate CALL 2 Quote the tax Returns amounts and the jurisdictions they belong to. Nothing is recorded. / tax-estimations CALL 3 Record the sale Only after payment succeeds, carrying the tax you quoted. / transactions Checkout Sequence Solid step numbers are the Kintsugi calls. Everything else happens in your storefront. 1 Cart assembled, address entered Your storefront. No Kintsugi call yet. 2 Validate the address POST /addresses/validate Recommended Returns standardizedAddress, the standardized and enriched version of what you sent. enrichedFields names the fields validation added or corrected, and verificationStatus says whether the address verified. An unverified address can resolve to the wrong jurisdiction. 3 Assemble the estimate request externalId date currency addresses transactionItems Each line needs an existing product record or an inline productCategory and productSubcategory pair. 4 Calculate tax POST /tax-estimations Returns a quote RETURNS Tax amounts broken out by the jurisdictions that levy them, on each line item's taxItems. A quote only: nothing is stored, and there is no estimate ID to track. 5 Show the total with tax Display the quoted amount before the customer pays, not after. 6 Process payment DECLINED → Send the customer back to the cart. The estimate was never recorded, so there is nothing to reverse in Kintsugi. 7 Sync the transaction with the tax amounts ## Tax Calculation Workflow POST /transactions Only after payment succeeds Send the tax you actually charged on each line's taxAmountImported. See Syncing Transaction Records. 8 Order complete The sale counts toward nexus and appears in filings. An estimate is not a record. If step 7 never runs, the sale is invisible to nexus and filings even though the customer was charged tax. ## Nexus and Tax Calculation Kintsugi calculates tax where you hold an active registration. The hasActiveRegistration flag on the response tells you which side of that line the transaction fell. When Tax Is Calculated Tax applies when: An active registration covers the customer's jurisdiction The product is taxable there No valid exemption covers the sale When Tax Is Zero Tax is zero when: No active registration covers that jurisdiction. hasActiveRegistration is then false and every amount is zero The product is exempt there A valid customer or line-level exemption applies In the exempt cases, exemptReason on the line item tells you which rule zeroed it out, for example PRODUCT, CUSTOMER, TRANSACTION, WHOLESALE, or REGION. Preview a registration before you make it: Set simulateActiveRegistration: true to see what the transaction would be taxed at if you were registered in the destination. Leave it false to see what you owe today. ## Customer Exemptions To have an exempt customer's status applied, reference the customer on the estimate: { "externalId": "txn-1001", "date": "2026-07-28T12:00:00Z", "currency": "USD", "customer": { "externalId": "cust-1001", "name": "Acme Corp" }, "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "country": "US" } ], "transactionItems": [ { "externalId": "item-1", "externalProductId": "sku-1001", "quantity": "2", "amount": "100.00" } ] } When the customer's externalId matches a customer Kintsugi holds, that customer's exemptions and tax registrations are applied to the estimate. Only an ACTIVE exemption is applied by tax calculation. For one-off exemptions that are not tied to a customer record, set exempt: true on the relevant line items instead. See the Product & Customer Records guide for how to create exempt customers. ## Error Handling Every error comes back in one envelope, { "code", "message", "requestId", "errors": [...] }. Common failures when calculating tax: Product cannot be priced: Send a known externalProductId, or a valid productCategory and productSubcategory pair. An unrecognized pair returns 400 Ambiguous product: An externalProductId that exists in more than one of your connections returns 400 without a Connection-Id header Invalid address: An address that cannot be validated returns 400; one in a country Kintsugi does not cover returns 422 No organization chosen: A key that reaches more than one organization must send a selector header, or gets 400 Missing required fields: externalId, date, currency, addresses, and transactionItems are all required, and so are externalId and amount on every line Missing or invalid API key: Every request needs a valid Api-Key header, or it returns 401 Service unavailable or rate limited: 503 and 429 are worth retrying with exponential backoff See the Error Handling guide for detailed strategies. ## Best Practices Request Structure Use consistent external IDs: Keep one identifier across the estimate and the transaction that follows it Validate addresses first: Verified addresses resolve to the right jurisdiction Reference products precisely: externalProductId values must match your product records Send complete line items: Every item needs an externalId and an amount Response Handling Store the response: Carry the same tax amounts into transaction sync Handle zero tax: No registration and valid exemptions are normal outcomes, not errors Show the breakdown: Surface taxItems so customers and your support team can see how tax was composed Parse decimals safely: Amounts and rates arrive as strings Performance Cache short-lived estimates: Reuse a result while the cart and address are unchanged Debounce address input: Wait for typing to settle before calling Fail gracefully: Decide in advance what checkout shows if an estimate fails Watch your call volume: Track usage so you see rate pressure before your customers do ## Integration Patterns E-Commerce Checkout Customer adds items to the cart Customer enters a shipping address Validate the address Calculate tax with POST /tax-estimations Display the total with tax Process payment Sync the transaction with those tax amounts Subscription Billing Customer selects a plan Customer provides a billing address Calculate tax for the first billing cycle Store the tax amount for recurring charges Recalculate when the address changes or the subscription renews Multi-Step Checkout Calculate tax once the shipping address step is complete Recalculate when the customer changes address Recalculate when the customer changes the cart Update the displayed total after each recalculation ## Reading the Tax Breakdown Each line item's taxItems array shows the tax applied per jurisdiction, for example a state tax and a county tax, each with its own name, rate, and amount. Together with the line's taxRate and taxAmount, and the transaction-level totalTaxAmount, that gives you a complete picture of the calculation. Use it to: Show customers how their tax was composed Produce receipts and invoices with real tax detail Debug unexpected results against a specific rate component Reconcile totals before you charge ## Next Steps With tax calculation integrated: Sync transactions: After payment, sync the sale with the tax amounts from the estimate. See the Syncing Transaction Records guide. Handle errors: Build the failure path before you need it. See the Error Handling guide. Tune performance: Cache and debounce to cut calls and keep checkout fast. For endpoint-level detail, see: Estimate tax on a transaction Validate and enrich an address --- # Error Handling (2026-10-06) Learn how to handle API errors and implement robust error handling Source: https://docs.trykintsugi.com/docs/2026-10-06/advanced/error-handling ## Error Response Format Every Tenanted API error comes back in one envelope, whatever the status: { "code": "not_found", "message": "The requested resource was not found.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } | Field | What it carries | | --- | --- | | code | A stable, machine-readable error code. Branch on this rather than on the message or the HTTP status. | | message | A human-readable description of the failure. Show it or log it, but do not parse it. | | requestId | The identifier for this request. Quote it when you report a failure so it can be traced. | | errors | One entry per request field that failed validation. Always present, and an empty list when the failure is not field-level. | When a request fails validation ( 422), each entry in errors names the field, says what is wrong with it, and explains it in words: { "code": "invalid_request", "message": "The request could not be validated.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [ { "field": "currency", "code": "missing", "message": "This field is required." }, { "field": "items[0].externalProductId", "code": "missing", "message": "This field is required." } ] } field is the path to the field in your request, under the field's documented camelCase name. Nested fields are dot-separated, and a list entry carries its position, as in items[0].externalProductId. The field-level code is one of four values: ## Error Response Format | Field code | Meaning | Message | | --- | --- | --- | | missing | A required field was not sent. | This field is required. | | invalid_type | The value is the wrong type, such as text where a number belongs. | The value is not of the type this field accepts. | | invalid_value | The value is the right type but not one the field accepts, such as an unknown enum member. | The value is not one this field accepts. | | out_of_range | The value is too long, too short, too large, or too small. | The value is outside the range this field accepts. | Some fields replace the generic message with a specific one. For example, an API key expiresAt in the past reports expiresAt must be in the future. ## HTTP Status Codes Client errors 4xx · 10 codes Fix the request, then retry. 400 Bad Request The request was invalid. Default code invalid_request 401 Unauthorized Authentication failed or was missing. Default code unauthorized 403 Forbidden The credential is not permitted for this request. Default code forbidden 404 Not Found The resource does not exist, or belongs to an organization your credential cannot reach. The two are deliberately identical. Default code not_found 405 Method Not Allowed The path exists but does not accept that method. The Allow header lists the methods it does accept. Default code method_not_allowed 409 Conflict The request conflicts with existing state, such as a duplicate create or a resource in the wrong state for the change. Default code conflict 410 Gone A link that was valid no longer accepts requests. Used by the public certificate-upload links. Default code gone 413 Payload Too Large The request body is larger than the endpoint accepts. Default code payload_too_large 422 Unprocessable Content The request failed validation, and the errors list names each field. Default code invalid_request 429 Too Many Requests The caller is over a rate or usage limit. Default code rate_limited Server errors 5xx · 2 codes Retry with backoff. 500 Internal Server Error An unexpected error prevented the request from completing. Default code error 503 Service Unavailable A service the request depends on was unavailable. Retry the request. Default code service_unavailable Several more specific codes also use 400, listed under Error Codes. ## Error Codes The code is the part of the response to build on. These are the codes the Tenanted API returns: ## Error Codes | Code | Status | What to do | | --- | --- | --- | | invalid_request | 400, 422 | Fix the request. On a 422, errors names each field. | | invalid_api_version | 400 | The Api-Version header is not a date. Send YYYY-MM-DD, or omit the header. | | unsupported_api_version | 400 | The Api-Version date is older than the earliest release. Send 2026-07-21 or later, or omit the header. | | missing_target_selector | 400 | Your credential reaches more than one organization. Send Organization-Id, Connection-Id, or Entity-Id. | | conflicting_target_selectors | 400 | The selectors you sent resolve to different organizations. Send one, or make them agree. | | multiple_organization_memberships | 400 | A signed-in session belongs to several organizations. Send Organization-Id to choose one. | | multiple_credentials | 400 | A credential-management endpoint received both an Api-Key and a bearer token. Send exactly one. | | stale_cursor | 400 | The pagination cursor was issued for a different query. Restart from the first page. | | unauthorized | 401 | Send a valid credential. | | forbidden | 403 | The credential cannot perform this operation. | | plan_upgrade_required | 403 | The action needs a paid plan or a premium entitlement. Upgrade the organization's plan. | | not_found | 404 | Check the ID and the organization you selected. | | method_not_allowed | 405 | Use a method from the Allow header. | | conflict | 409 | Read the message: the resource already exists or is in the wrong state. | | entity_resolution_ambiguous | 409 | Entity-Id matches more than one connection. Add Entity-Source or Connection-Id. | | gone | 410 | The link is finished. Ask whoever sent it for a new one. | | payload_too_large | 413 | Shrink the body, for example by compressing or splitting a file. | | rate_limited | 429 | Slow down, then retry. | | service_unavailable | 503 | Retry with backoff. The same request may succeed on a later attempt. | | error | 500 | Retry with backoff, and quote the requestId if it persists. | ## Error Codes Three further codes, missing_portfolio_selector, multiple_portfolio_memberships, and TEST_PARTNER_INACTIVE, apply only to partner portfolio credentials. ## Common Error Messages Authentication Errors Missing or Invalid API Key Error Response { "code": "unauthorized", "message": "Invalid API key.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } Solution Send your API key in the Api-Key header: curl -H "Api-Key: $KINTSUGI_API_KEY" \ https://api.trykintsugi.com/products/categories Verify the key is correct and complete Check it has not expired or been deleted Check the header is named Api-Key The message varies with the cause, so branch on code: "unauthorized" rather than on the text. Session Token Required Error Response { "code": "unauthorized", "message": "Provide a bearer token.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } Solution The Users and API Keys endpoints manage people and credentials, and they do not accept an organization API key. Send a signed-in user's session token as Authorization: Bearer . See Endpoints That Take a Session Token. Organization Not Found Error Response { "code": "not_found", "message": "The requested resource was not found.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } Solution An Organization-Id, Connection-Id, or Entity-Id that names an organization your credential cannot reach returns the same 404 as one that does not exist. A key created in the app acts on its own organization and needs no selector, so remove the header or correct it: curl -H "Api-Key: $KINTSUGI_API_KEY" \ -H "Organization-Id: $KINTSUGI_ORG_ID" \ https://api.trykintsugi.com/products List organizations returns every organization your credential can access, with the ID to use. Not Permitted Error Response { "code": "forbidden", "message": "Your credential is not permitted to perform this operation.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } Solution ## Common Error Messages Your credential reached the organization but cannot perform this operation. Managing users and API keys, for example, takes a signed-in user with the Owner or Admin role. Plan Upgrade Required Error Response { "code": "plan_upgrade_required", "message": "A paid plan is required to view a billing estimate.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } Solution The request is valid and authenticated, but the organization's current plan does not include the action. Upgrade the plan, then retry. Branch on the code, not the message, to offer an upgrade in your own product. Validation Errors Missing Required Fields { "code": "invalid_request", "message": "The request could not be validated.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [ { "field": "externalId", "code": "missing", "message": "This field is required." } ] } Solution: Include every required field. The reference marks each one, and field names the one that is missing. Invalid Field Values { "code": "invalid_request", "message": "The request could not be validated.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [ { "field": "addresses[0].type", "code": "invalid_value", "message": "The value is not one this field accepts." } ] } Solution: Use a value the field accepts. The reference lists the members of every enum. Business Logic Violations { "code": "invalid_request", "message": "originalTransactionId may only be sent when type is a credit-note type.", "requestId": "req_8f3k2mNpQr7Ls", "errors": [] } Solution: A rule that spans more than one field comes back as a 400 with the rule in message and an empty errors list. Adjust the request so the fields agree. ## Error Handling Best Practices Branch on the Error Code Read the envelope and handle each code appropriately: import requests response = requests.get(url, headers=headers) if not response.ok: error = response.json() code = error["code"] if code == "unauthorized": \# Handle authentication error print("Invalid or missing credential") elif code == "rate_limited": \# Handle rate limiting print("Rate limited. Slow down and retry.") elif code == "invalid_request": \# Handle validation errors for field_error in error["errors"]: print(f"{field_error['field']}: {field_error['message']}") if not error["errors"]: print(error["message"]) elif code == "stale_cursor": \# Restart pagination from the first page print("Cursor no longer valid. Restarting from the first page.") Implement Exponential Backoff For rate limiting and temporary errors, retry with exponential backoff: import random import time import requests \# rate_limited, error, service_unavailable RETRYABLE_STATUSES = {429, 500, 503} def make_request_with_retry(url, headers, max_retries=3): for attempt in range(max_retries): response = requests.get(url, headers=headers) if response.ok: return response if response.status_code not in RETRYABLE_STATUSES: response.raise_for_status() \# Exponential backoff with jitter wait_time = (2 ** attempt) + random.uniform(0, 1) time.sleep(wait_time) raise Exception("Max retries exceeded") Log Errors Appropriately Log errors with enough context to trace them, and always keep the requestId: import logging import requests logger = logging.getLogger(__name__) ## Error Handling Best Practices response = requests.get(url, headers=headers) if not response.ok: error = response.json() logger.error( "API request failed", extra={ "status_code": response.status_code, "url": url, "code": error.get("code"), "request_id": error.get("requestId"), "message": error.get("message"), } ) response.raise_for_status() Provide User-Friendly Error Messages Transform error codes into messages your own users can act on: def handle_api_error(error): code = error.get("code") if code == "unauthorized": return "Please check your API key and try again." elif code == "not_found": return "The requested resource was not found." elif code == "invalid_request": return "Please check your input data and try again." elif code == "rate_limited": return "Too many requests. Please wait a moment and try again." else: return "An unexpected error occurred. Please try again later." ## Troubleshooting Common Issues Authentication Issues Missing or Invalid API Key Error: 401 with code unauthorized Solution: Send your key in the Api-Key header, and check it has not expired or been deleted: curl -H "Api-Key: $KINTSUGI_API_KEY" \ https://api.trykintsugi.com/products/categories The Tenanted API uses Api-Key, not the v1 x-api-key header, and a key created in the app needs no organization header. Session Token Required Error: Provide a bearer token. Solution: Users and API Keys endpoints do not accept an organization API key. Send a signed-in user's session token as Authorization: Bearer . Validation Issues Missing Required Fields Error: This field is required. on a field with code missing Solution: Check the reference for required fields and include each one in your request body. field names the one that is missing. Invalid Data Types Error: The value is not of the type this field accepts. or The value is not one this field accepts. Solution: Use the type and enum values the reference lists for the field. Money amounts are decimal strings, and timestamps are RFC 3339 UTC ending in Z. Resource Issues Resource Not Found Error: The requested resource was not found. Solution: Verify the resource ID is correct Check the resource belongs to an organization your credential can reach Check any Organization-Id, Connection-Id, or Entity-Id you sent Choosing an Organization Error: Provide one of Organization-Id, Connection-Id, or Entity-Id. Solution: Your credential reaches more than one organization, so a write has to name one. Send Organization-Id with the ID from List organizations. ## Related Resources Getting Started Authenticating Your Requests API Reference Support --- # API Lab (2026-10-06) Interactive, runnable walkthroughs for the Kintsugi API. Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes Each recipe is a hands-on walkthrough of a common Kintsugi workflow. Open one to step through the calls, edit the requests, and see the responses. Estimate Tax Calculate tax for a transaction before you commit it, using live inputs for addresses, products, and exemptions. Open API Lab → Managing Products Create products, fetch categories, and retrieve product details so items are classified correctly for tax. Open API Lab → Managing Customers Create customer records and look them up. The foundation for exemptions and customer-level reporting. Open API Lab → Creating Transactions Record completed sales and retrieve them, keeping your compliance data in sync with every order. Open API Lab → Creating Credit Notes Issue credit notes for refunds and returns so your sales records stay accurate. Open API Lab → Managing Nexus Create physical nexus and registrations, then confirm where your business has tax obligations. Open API Lab → --- # Calculate Tax for a Transaction (2026-10-06) Interactive walkthrough to calculate tax using the Kintsugi API Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes/calculate-tax ## Overview The Tax Estimation API calculates the tax due on a transaction before you record it, using your registrations, product taxability, customer exemptions and the addresses on the transaction. Nothing is stored and the estimate cannot be retrieved afterwards, so send the same request again whenever you need to price it again. That makes it a natural fit for checkout flows and for testing tax calculations. ## When to Use Shopping cart pages: Calculate tax when customers review their order Checkout flows: After address entry but before payment processing Subscription billing: Calculate tax for recurring charges Quote generation: Provide tax estimates to customers ## Authentication This endpoint takes one credential header: Api-Key: Your API key The estimate is computed for exactly one organization. If your key can reach more than one organization, send an Organization-Id, Connection-Id or Entity-Id header to choose it. Send Api-Version: 2026-10-06 to run against this release; a request without it runs against 2026-07-21. The lab sends this release's request shapes. The examples on this page are written for 2026-07-21; the API changelog lists what changed since. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Estimate tax on a transaction POST /tax-estimations Edit the addresses or line items to shape the request. Because this lab is simulated, the returned figures are illustrative rather than live jurisdiction rates. { "externalId": "txn-1001", "date": "2026-07-28T12:00:00Z", "currency": "USD", "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "countryCode": "US" } ], "transactionItems": [ { "externalId": "item-1", "externalProductId": "sku-1001", "productName": "Widget", "quantity": "2", "amount": "100.00" } ] } { "externalId": "txn-1001", "date": "2026-07-28T12:00:00Z", "currency": "USD", "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "countryCode": "US" } ], "transactionItems": [ { "externalId": "item-1", "externalProductId": "sku-1001", "productName": "Widget", "quantity": "2", "amount": "100.00" } ] } Run ## Required Fields externalId: Your identifier for the transaction, echoed on the response date: When the transaction takes place; the rates in force on this date are applied currency: ISO 4217 currency of every amount on the request (for example, USD) addresses: The addresses on the transaction, each with a type. Supply at least a SHIP_TO or BILL_TO; tax is sourced to the SHIP_TO address when one is supplied, otherwise BILL_TO transactionItems: At least one line, each with an externalId and an amount Each line names either an externalProductId you have already created or a productCategory and productSubcategory pair, not both. Tax is only due where an active registration covers the destination. When hasActiveRegistration is false, every amount comes back as zero. Set simulateActiveRegistration to true to see what the transaction would be taxed at if you were registered there. ## Common Use Cases Basic Tax Calculation Calculate tax for a simple transaction with one address: { "externalId": "txn-1001", "date": "2026-07-28T12:00:00Z", "currency": "USD", "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "country": "US" } ], "transactionItems": [ { "externalId": "item-1", "externalProductId": "sku-1001", "productName": "Widget", "quantity": "2", "amount": "100.00" } ] } With Customer Information Include the buyer so their exemptions apply. When the customer's externalId matches a customer Kintsugi already holds, that customer's exemptions and tax registrations are applied to the estimate: { "externalId": "txn-1001", "date": "2026-07-28T12:00:00Z", "currency": "USD", "customer": { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com" }, "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "country": "US" } ], "transactionItems": [ { "externalId": "item-1", "externalProductId": "sku-1001", "productName": "Widget", "quantity": "2", "amount": "100.00" } ] } ## Response Fields totalTaxAmount: Total tax due on the transaction taxableAmount: Total across all lines that tax was charged on taxRate: Combined effective rate across the transaction, as a fraction of the taxable amount hasActiveRegistration: Whether an active registration covers the destination jurisdiction; when false, no tax is due and every amount is zero ## Next Steps Create a Transaction - Record the transaction after payment Sales Tax Calculations Guide - Learn more about tax calculation Getting Started - Set up your integration ## Related Resources Tax Estimation API Reference Sales Tax for Developers Support --- # Create a Product (2026-10-06) Interactive walkthrough to create products using the Kintsugi API Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes/managing-products ## Overview Products in Kintsugi represent the items you sell. Each product needs a tax classification, a category and subcategory, so tax is calculated accurately. This endpoint creates a new product record that is used for tax calculations in transactions. Creating a product is idempotent on externalId and source: sending the same values again returns the existing product unchanged with 200 instead of creating a duplicate. To change a product, use Update a product. ## When to Use Product catalog setup: Create products when setting up your integration New product launches: Add new products as you expand your catalog Tax classification: Ensure products have proper tax categories for accurate calculations Manual product management: Create products outside of automated syncs ## Authentication This endpoint takes one credential header: Api-Key: Your API key Send Api-Version: 2026-10-06 to run against this release; a request without it runs against 2026-07-21. The lab sends this release's request shapes. The examples on this page are written for 2026-07-21; the API changelog lists what changed since. When your key can reach more than one organization, add an Organization-Id, Connection-Id or Entity-Id header to choose which one the product is created in. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create a product POST /products { "externalId": "sku-1001", "name": "Blue T-Shirt", "status": "APPROVED", "productCategory": "Physical", "productSubcategory": "General Clothing", "taxExempt": false, "source": "API" } { "externalId": "sku-1001", "name": "Blue T-Shirt", "status": "APPROVED", "productCategory": "Physical", "productSubcategory": "General Clothing", "taxExempt": false, "source": "API" } Run 2 List the product category catalog GET /products/categories Browse the categories you can assign to a product. Run 3 Get a product by id GET /products/{product_id} Run Run the previous step to fill the path. ## Required Fields externalId: Your stable identifier for the product name: Human-readable product name productCategory: Top-level tax category: Digital, Misc, Physical or Services (see List the product category catalog) productSubcategory: Tax subcategory label within the category (see List the product category catalog). An unrecognized category and subcategory pair returns 400 taxExempt: Whether tax calculation treats the product as tax-exempt ## Common Use Cases Basic Product Creation Create a product with only the required fields: { "externalId": "sku-1001", "name": "Blue T-Shirt", "productCategory": "Physical", "productSubcategory": "General Clothing", "taxExempt": false } Product with Full Details Include the classification status and the source system: { "externalId": "sku-1001", "name": "Blue T-Shirt", "status": "APPROVED", "productCategory": "Physical", "productSubcategory": "General Clothing", "taxExempt": false, "source": "API" } status accepts APPROVED, PARTIALLY_APPROVED or PENDING. It does not accept ARCHIVED; archive an existing product with Archive a product. source defaults to OTHER and must be a supported public value. ## Response Fields id: Kintsugi's unique identifier for the product externalId: Your stable identifier for the product, as supplied on create name: Human-readable product name productCategory: Derived display category for the product's tax code productSubcategory: Derived display subcategory for the product's tax code status: Approval status of the product's tax classification (APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED) taxExempt: Effective tax-exemption flag applied by tax calculation source: Origin system of the product, such as API or SHOPIFY ## Product Categories Before creating products, fetch the available categories and subcategories with List the product category catalog. Each entry's category and each subcategory's label are the exact values productCategory and productSubcategory accept. Together, productCategory and productSubcategory resolve to a product tax code. Choose the most specific category and subcategory that matches your product to ensure accurate tax calculations. ## Next Steps List the product category catalog - View all available categories and subcategories List products - List and search your products Get a product by id - Retrieve a specific product Update a product - Modify product details Product & Customer Records Guide - Learn more about product management ## Related Resources Products API Reference Getting Started Support --- # Managing Customers (2026-10-06) Interactive walkthrough for creating customers and retrieving customer records Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes/managing-customers ## Overview Customer records in Kintsugi store customer information and enable exemption management. While not required for all integrations, customer records are essential when dealing with tax-exempt customers (nonprofits, resellers, etc.) or when you need to track customer-specific tax information. ## When to Create Customer Records Tax-exempt customers: Nonprofits, resellers, or other exempt entities Customer exemptions: When customers have jurisdiction-specific exemptions Customer tracking: When you need to maintain customer tax history A transaction does not need a separate customer record. You can pass the buyer's details in the customer object of a transaction request, or omit it for a sale with no customer identity. ## Workflow Create a Customer - Create a customer record with address information Retrieve Customers - Search and retrieve customer records ## Step 1: Create a Customer Create a customer record using the API Lab below with POST /customers. Example Request { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94105", "country": "US" } Creating a customer is idempotent on externalId and source: sending the same values again returns the existing customer unchanged with 200 instead of creating a duplicate. A new customer is always ACTIVE. To change a customer, use Update a customer. ## Step 2: Retrieve Customers After creating customers, retrieve them using GET /customers. You can: Search with the search parameter, which matches a customer's id, externalId and externalFriendlyId exactly, and its name and email as a case-insensitive substring Filter by country and state Page through all customers with limit and the cursor from a prior response's nextCursor or previousCursor ## Authentication These endpoints take one credential header: Api-Key: Your API key Send Api-Version: 2026-10-06 to run against this release; a request without it runs against 2026-07-21. The lab sends this release's request shapes. The examples on this page are written for 2026-07-21; the API changelog lists what changed since. When your key can reach more than one organization, add an Organization-Id, Connection-Id or Entity-Id header to choose which one the request targets. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create a customer POST /customers Send a customer record. The response returns the new customer, including its id. { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94105", "countryCode": "US" } { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94105", "countryCode": "US" } Run 2 Get a customer by id GET /customers/{customer_id} Fetch the customer you just created. The id from step 1 fills the path automatically. Run Run the previous step to fill the path. ## Required Fields The request schema marks no field as required. Send an externalId: it is your stable identifier for the customer and the key that makes creation idempotent. ## Common Use Cases Basic Customer Creation Create a customer with an identifier, a name and an address: { "externalId": "cust-1001", "name": "Acme Corp", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94105", "country": "US" } Customer with Full Details Include complete customer information, including a tax registration: { "externalId": "cust-1001", "name": "Acme Corp", "companyName": "Acme Corp", "email": "jane.doe@example.com", "phone": "+1 415 555 0100", "source": "API", "taxRegistrations": [ { "countryCode": "CA", "taxType": "gst", "taxId": "123456789RT0001" } ], "street1": "123 Main St", "street2": "Suite 400", "city": "San Francisco", "county": "San Francisco County", "state": "CA", "postalCode": "94105", "country": "US" } Each tax registration needs a countryCode, taxType and taxId, and a customer holds one registration per countryCode and taxType pair. Exempt Customer Creating a customer does not record an exemption. Create the customer as in Step 1, then record the exemption with Create an exemption, passing the customer's id as customerId. ## Response Fields id: Kintsugi's unique identifier for the customer externalId: Your stable identifier for the customer name: Customer name email: Contact email address status: Whether the customer record is in use or retired (ACTIVE, ARCHIVED) addressStatus: Whether the customer's address has been validated ## Next Steps List customers - List and search customers Get a customer by id - Retrieve a specific customer Update a customer - Modify customer details Product & Customer Records Guide - Learn more about customer management ## Related Resources Customers API Reference Getting Started Support --- # Creating Transactions (2026-10-06) Interactive walkthrough for creating transactions and retrieving transaction records Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes/creating-transactions ## Overview Transactions represent completed sales in Kintsugi. Each transaction records a sale with customer information, line items, addresses, and tax details. Transactions are used for compliance tracking, nexus determination, and tax filing preparation. Only create transactions for completed sales with confirmed payment. Do not sync pending orders or estimates. ## When to Create Transactions After payment confirmation: When a sale is completed and payment is received Order fulfillment: When an order is shipped or delivered Invoice creation: When generating invoices for completed sales Batch sync: Daily or periodic syncing of completed orders ## Workflow Create a Transaction - Record a completed sale Retrieve Transactions - Search and retrieve transaction records ## Step 1: Create a Transaction Create a transaction using the API Lab below with POST /transactions. Example Request { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "description": "Order 2001", "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "country": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } The API answers 202 Accepted. The transaction is recorded immediately and tax is calculated afterwards, so the response shows processingStatus QUEUED with tax totals of "0.00". totalTaxAmountCalculated and each line's taxItems populate once processing completes. The returned id is not fetchable straight away: GET /transactions/{transaction_id} answers 404 until processing completes. Poll it rather than treating the first 404 as a failure. externalId is your stable identifier for the transaction. Sending the same one again updates the existing transaction rather than creating a second. ## Step 2: Retrieve Transactions After creating transactions, retrieve them using GET /transactions. You can: Search with the search parameter, which covers the transaction id, externalId, externalFriendlyId, description and customer name Filter by date range using startDate and endDate ( YYYY-MM-DD) Filter by status, state, country, and more Page through results with limit and the cursor from a prior response's nextCursor or previousCursor The list is sorted by date, newest first, unless you set sort and order. ## Authentication These endpoints take one credential header: Api-Key: Your API key Send Api-Version: 2026-10-06 to run against this release; a request without it runs against 2026-07-21. The lab sends this release's request shapes. The examples on this page are written for 2026-07-21; the API changelog lists what changed since. When your key can reach more than one organization, add an Organization-Id, Connection-Id or Entity-Id header to choose which one the request targets. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create a transaction POST /transactions Record a completed sale. The API answers 202 Accepted and calculates tax afterwards, so processingStatus starts at QUEUED. { "externalId": "order-1001", "date": "2026-07-21T15:30:00Z", "type": "SALE", "originalTransactionId": "tran_12345", "currency": "AED", "totalAmount": "10.00", "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "street2": "Suite 400", "city": "San Francisco", "county": "San Francisco County", "state": "CA", "postalCode": "94107", "countryCode": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "3", "amount": "10.00", "product": "Widget", "description": "Annual software subscription", "externalId": "order-1001", "taxAmountImported": "10.00", "taxableAmount": "10.00" } ], "customer": { "externalId": "order-1001", "name": "Acme Corp", "email": "jane.doe@example.com", "companyName": "Acme Corp" }, "description": "Annual software subscription", "marketplace": false, "source": "API" } ## Try It Out { "externalId": "order-1001", "date": "2026-07-21T15:30:00Z", "type": "SALE", "originalTransactionId": "tran_12345", "currency": "AED", "totalAmount": "10.00", "addresses": [ { "type": "BILL_TO", "street1": "123 Main St", "street2": "Suite 400", "city": "San Francisco", "county": "San Francisco County", "state": "CA", "postalCode": "94107", "countryCode": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "3", "amount": "10.00", "product": "Widget", "description": "Annual software subscription", "externalId": "order-1001", "taxAmountImported": "10.00", "taxableAmount": "10.00" } ], "customer": { "externalId": "order-1001", "name": "Acme Corp", "email": "jane.doe@example.com", "companyName": "Acme Corp" }, "description": "Annual software subscription", "marketplace": false, "source": "API" } Run 2 Get a transaction by id GET /transactions/{transaction_id} Read the transaction back. On the live API this returns 404 until processing has finished. Run Run the previous step to fill the path. ## Required Fields externalId: Your stable identifier for the transaction date: When the transaction occurred. This drives which filing period it lands in, so send the real transaction time, not the time of the call currency: ISO 4217 currency of every amount sent (for example, USD) Within the optional arrays, each address needs a type, and each line in items needs an externalProductId and a date. type defaults to SALE. Tax jurisdiction is resolved from addresses, so an incomplete address means tax cannot be calculated accurately. ## Common Use Cases Basic Transaction Create a simple transaction with one address and one line: { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "country": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } Transaction with Customer Include customer information. Omit customer for a sale with no customer identity, such as a marketplace or point-of-sale transaction; the transaction is then attributed to your organization's shared unattributed-sales customer. { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "customer": { "externalId": "cust-1001", "name": "Acme Corp", "email": "jane.doe@example.com" }, "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "country": "US" } ], "items": [ { "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } ## Response Fields id: Kintsugi's unique identifier for the transaction externalId: Your stable identifier for the transaction date: When the transaction occurred; this drives filing-period assignment totalAmount: Total transaction amount totalTaxAmountCalculated: Total tax Kintsugi calculated status: Settlement state of the transaction processingStatus: How far the transaction has progressed through processing; PROCESSED means tax calculation has completed ## Next Steps List transactions - List and search transactions Get a transaction by id - Retrieve a specific transaction Update a transaction - Modify transaction details Syncing Transaction Records - Learn more about transaction management ## Related Resources Transactions API Reference Getting Started Support --- # Creating Credit Notes (2026-10-06) Interactive walkthrough for creating credit notes (refunds) for sale transactions Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes/creating-credit-notes ## Overview Credit notes represent refunds, returns, or adjustments to original transactions. They maintain accurate sales records by reducing taxable amounts when refunds occur, ensuring your tax filings reflect net sales (sales minus refunds) rather than gross sales. In the Tenanted API a credit note is a transaction. You create one with POST /transactions, setting type to a credit-note type and naming the sale it reverses in originalTransactionId. You must have the Kintsugi transaction ID (the id, not your externalId) of the original transaction to create a credit note. Store transaction IDs after creating transactions for future credit note creation. ## When to Create Credit Notes Full refunds: When a customer returns an entire order Partial refunds: When a customer returns specific items Order cancellations: When an order is cancelled after payment Price adjustments: When correcting pricing errors ## Prerequisites Before creating a credit note, you need: The original transaction must exist in Kintsugi The original transaction must be a sale whose status is PENDING, COMMITTED, or PARTIALLY_REFUNDED The Kintsugi transaction ID (not the externalId) An externalId on each original line you plan to credit, since every credited line must reference one ## Workflow Find Original Transaction - Retrieve the original transaction to get its Kintsugi ID Create Credit Note - Create a credit note linked to the original transaction Retrieve Credit Notes - Verify the credit note was created ## Step 1: Find Original Transaction If you don't have the Kintsugi transaction ID, find it using: GET /transactions?search={externalId} - The search parameter covers externalId, along with the transaction id, externalFriendlyId, description and customer name GET /transactions/{transaction_id} - Read back a transaction you already hold the ID for, including its lines ## Step 2: Create Credit Note Create a credit note using the API Lab below with POST /transactions, a credit-note type and originalTransactionId. The credit note inherits the original transaction's customer, addresses and source, so send only the lines to credit in items. Each line carries the externalId of the original line it reverses, the externalProductId of the product on that line, and a taxableAmount. Example Request { "externalId": "cn-1", "date": "2026-07-21T15:30:00Z", "type": "FULL_CREDIT_NOTE", "originalTransactionId": "tran_12345", "currency": "USD", "totalAmount": "100.00", "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "2", "amount": "100.00", "taxableAmount": "100.00" } ] } Send amounts as positive values; the stored credit note reads them back as negative. The API answers 202 Accepted. The stored type is derived from the amount credited, so a FULL_CREDIT_NOTE that credits less than the sale reads back as PARTIAL_CREDIT_NOTE, and the reverse. Sending the same credit-note externalId against the same original transaction again returns the stored credit note rather than a conflict. The same externalId against a different original transaction conflicts. ## Step 3: Retrieve Credit Notes Retrieve the credit notes for a sale with GET /transactions/{transaction_id}/related, passing the original transaction's ID. It lists the credit notes that reverse a sale, or, from a credit note, the original sale it reverses. Credit notes also appear in transaction queries. Use GET /transactions with: type: Filter by CREDIT_NOTE, which groups every credit-note type search: Search by credit note externalId ## Authentication These endpoints take one credential header: Api-Key: Your API key Send Api-Version: 2026-10-06 to run against this release; a request without it runs against 2026-07-21. The lab sends this release's request shapes. The examples on this page are written for 2026-07-21; the API changelog lists what changed since. When your key can reach more than one organization, add an Organization-Id, Connection-Id or Entity-Id header to choose which one the request targets. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Create the original transaction POST /transactions { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "description": "Order 2001", "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "countryCode": "US" } ], "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } { "externalId": "order-2001", "date": "2026-01-15T14:30:00Z", "type": "SALE", "currency": "USD", "totalAmount": "100.00", "source": "API", "description": "Order 2001", "addresses": [ { "type": "SHIP_TO", "street1": "123 Main St", "city": "San Francisco", "state": "CA", "postalCode": "94107", "countryCode": "US" } ], "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-01-15T14:30:00Z", "product": "Widget", "quantity": "2", "amount": "100.00" } ] } Run 2 Issue a credit note POST /transactions A credit note is a transaction too. The sale's id from step 1 fills originalTransactionId automatically. { "externalId": "cn-1", "date": "2026-07-21T15:30:00Z", "type": "FULL_CREDIT_NOTE", "originalTransactionId": "tran_12345", "currency": "USD", "totalAmount": "100.00", "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "2", "amount": "100.00", "taxableAmount": "100.00" } ] } ## Try It Out { "externalId": "cn-1", "date": "2026-07-21T15:30:00Z", "type": "FULL_CREDIT_NOTE", "originalTransactionId": "tran_12345", "currency": "USD", "totalAmount": "100.00", "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "2", "amount": "100.00", "taxableAmount": "100.00" } ] } Run Run the previous step to fill the request. ## Required Fields externalId: Your unique credit note identifier date: When the credit note was issued currency: ISO 4217 currency of every amount sent (for example, USD) type: FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE originalTransactionId: The Kintsugi ID of the committed sale being reversed items: At least one line to credit, each with: externalId: The externalId of the original line being reversed externalProductId: The product on that original line date: Date and time of the line taxableAmount: The taxable portion being reversed on that line The schema itself requires only externalId, date and currency. The other fields are required when type is a credit-note type, and a request without them is rejected with 400. ## Common Use Cases Full Refund Create a credit note for a full refund: { "externalId": "cn-1", "date": "2026-07-21T15:30:00Z", "type": "FULL_CREDIT_NOTE", "originalTransactionId": "tran_12345", "currency": "USD", "totalAmount": "100.00", "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "2", "amount": "100.00", "taxableAmount": "100.00" } ] } Partial Refund Create a credit note for a partial refund: { "externalId": "cn-2", "date": "2026-07-21T15:30:00Z", "type": "PARTIAL_CREDIT_NOTE", "originalTransactionId": "tran_12345", "currency": "USD", "totalAmount": "40.00", "items": [ { "externalId": "item-1", "externalProductId": "SKU-ABC", "date": "2026-07-21T15:30:00Z", "quantity": "1", "amount": "40.00", "taxableAmount": "40.00" } ] } A credit note cannot credit more than is still creditable on the original transaction, or on any original line. ## Response Fields id: Kintsugi's unique identifier for the credit note externalId: Your stable identifier for the credit note date: When the credit note was issued totalAmount: Total transaction amount taxableAmount: Portion of the total that tax was assessed on type: Document shape of the transaction (FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE) status: Settlement state of the transaction ## Next Steps List transactions - List and search credit notes List related transactions - List the credit notes that reverse a sale Update a credit note - Modify credit note details Handling Refund Transactions - Learn more about credit notes ## Related Resources Create a Transaction API Reference Getting Started Support --- # Managing Nexus (2026-10-06) Interactive walkthrough for creating physical nexus, registrations, and retrieving nexus information Source: https://docs.trykintsugi.com/docs/2026-10-06/recipes/managing-nexus ## Overview Nexus determines where your business has a tax obligation. Physical nexus represents business locations (offices, warehouses, employees), while registrations represent jurisdictions where you're registered to collect and remit sales tax. This API Lab covers managing both physical nexus and registrations. ## Understanding Nexus Types Physical Nexus: Business locations that create tax obligations (offices, warehouses, employees) Registrations: Jurisdictions where you're registered to collect and remit tax ## Workflow Create Physical Nexus - Record a physical business location Create Registration - Register in a jurisdiction Retrieve Physical Nexus - View all physical nexus records Retrieve Registrations - View all registrations ## Step 1: Create Physical Nexus Create a physical nexus record using the API Lab below with POST /physical-nexus. Example Request { "countryCode": "US", "stateCode": "CA", "category": "PHYSICAL_BUSINESS_LOCATION", "startDate": "2026-01-01" } Recording a presence can establish nexus in the jurisdiction, so its exposure is recalculated. One record exists per organization, jurisdiction and category: a second create for the same three returns 200. A category the jurisdiction does not accept returns 400; get the accepted set from GET /physical-nexus/categories. ## Step 2: Create Registration Create a registration using POST /registrations. This represents a jurisdiction where you're registered to collect tax. Example Request { "countryCode": "US", "stateCode": "CA", "filingFrequency": "UNKNOWN", "registrationDate": "2026-01-01" } Send filingFrequency UNKNOWN when the jurisdiction has not assigned one yet; Kintsugi replaces it once it does. registrationImportType defaults to REGULAR, a direct registration identified by countryCode and stateCode. ## Step 3: Retrieve Physical Nexus Retrieve physical nexus records using GET /physical-nexus. You can filter by: countryCode: Filter by countries (comma-separated) stateCode: Filter by states (comma-separated) Pagination: Use limit and the cursor from a prior response's nextCursor or previousCursor ## Step 4: Retrieve Registrations Retrieve registrations using GET /registrations. You can filter by: countryCode: Filter by countries (comma-separated) stateCode: Filter by states (comma-separated) status: Filter by registration status (comma-separated) Pagination: Use limit and the cursor from a prior response's nextCursor or previousCursor ## Authentication These endpoints take one credential header: Api-Key: Your API key Send Api-Version: 2026-10-06 to run against this release; a request without it runs against 2026-07-21. The lab sends this release's request shapes. The examples on this page are written for 2026-07-21; the API changelog lists what changed since. When your key can reach more than one organization, add an Organization-Id, Connection-Id or Entity-Id header to choose which one the request targets. ## Try It Out API Lab Simulated Run all Reset Share Copy cURL Postman Runs in a simulated sandbox. Responses are generated from the API schema so you can explore each call safely; they never reach the live API, so the values are illustrative. 1 Record a physical presence POST /physical-nexus { "countryCode": "US", "stateCode": "CA", "category": "PHYSICAL_BUSINESS_LOCATION", "startDate": "2026-01-01" } { "countryCode": "US", "stateCode": "CA", "category": "PHYSICAL_BUSINESS_LOCATION", "startDate": "2026-01-01" } Run 2 Create a registration POST /registrations { "countryCode": "US", "stateCode": "CA", "filingFrequency": "UNKNOWN", "registrationDate": "2026-01-01" } { "countryCode": "US", "stateCode": "CA", "filingFrequency": "UNKNOWN", "registrationDate": "2026-01-01" } Run 3 List nexus determinations GET /nexus Read back the nexus footprint for your organization. Run ## Required Fields Physical Nexus countryCode: ISO 3166-1 alpha-2 country of the jurisdiction (for example, US) stateCode: State or province code within countryCode (for example, CA) category: Kind of physical presence to record (for example, PHYSICAL_BUSINESS_LOCATION) startDate: Date the physical presence began, as YYYY-MM-DD Registration countryCode: ISO 3166-1 alpha-2 country to register in (for example, US) filingFrequency: How often returns should be filed (for example, MONTHLY, or UNKNOWN when none is assigned yet) stateCode is optional: omit it for a country-level registration. ## Common Use Cases Physical Business Location Create nexus for a physical office or warehouse: { "countryCode": "US", "stateCode": "CA", "category": "PHYSICAL_BUSINESS_LOCATION", "startDate": "2026-01-01", "externalId": "hris-4471", "street1": "123 Main St", "street2": "Suite 400", "city": "San Francisco", "postalCode": "94107" } Add an endDate ( YYYY-MM-DD, not before startDate) when the presence has ended; omit it while the presence is open-ended. Registration Create a registration for a jurisdiction: { "registrationImportType": "REGULAR", "countryCode": "US", "stateCode": "CA", "stateName": "California", "filingFrequency": "UNKNOWN", "registrationDate": "2026-01-01", "salesTaxId": "123-456789" } salesTaxId is the account number the jurisdiction issued, on a registration you already hold. ## Response Fields Record a physical presence id: Opaque unique identifier for this physical nexus externalId: Your identifier for this record in an external system countryCode: ISO 3166-1 alpha-2 country of the jurisdiction stateCode: State or province code within countryCode startDate: Date the physical presence began, as YYYY-MM-DD endDate: Date the physical presence ended, as YYYY-MM-DD; null while open-ended category: Kind of physical presence the record holds Create a registration id: Kintsugi's unique identifier for the registration countryCode: ISO 3166-1 alpha-2 country the registration is held in stateCode: State or province code the registration is held in status: Where the registration stands in onboarding and filing filingFrequency: How often returns are filed against the registration registrationDate: Date the registration takes effect in the jurisdiction, as YYYY-MM-DD ## Next Steps List physical presences - List physical nexus List registrations - List registrations Update a physical presence - Modify nexus details Update a registration - Modify registration details ## Related Resources Nexus API Reference Registrations API Reference Getting Started Support --- # Search POST /v1/address_validation/search Source: https://docs.trykintsugi.com/reference/search POST /v1/address_validation/search Search This API validates and enriches address information submitted by the user. It ensures that the address is standardized, accurate, and compliant with geographical and postal standards. The API also adds additional fields, such as county, when possible. Category: Address Validation Request body: phone (string) - Phone number associated with the address. street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields. Response fields: address_submitted (AddressSubmittedResponse, required) - The original address data submitted in the request street_1 (string) - Primary street address of the customer street_2 (string) - Additional street address details, such as an apartment or suite number city (string) - City where the customer resides county (string) - County or district of the customer state (string) - State or province of the customer postal_code (string) - ZIP or Postal code of the customer country (string) - Country code in ISO 3166-1 alpha-2 format full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields response_address (AddressResponseData, required) - The standardized and enriched version of the submitted address street_1 (string) - Primary street address of the customer street_2 (string) - Additional street address details, such as an apartment or suite number city (string) - City where the customer resides county (string) - County or district of the customer state (string) - State or province of the customer postal_code (string) - ZIP or Postal code of the customer country (string) - Country code in ISO 3166-1 alpha-2 format [truncated, see the reference page] --- # Suggestions POST /v1/address_validation/suggestions Source: https://docs.trykintsugi.com/reference/suggestions POST /v1/address_validation/suggestions Suggestions This API endpoint provides address suggestions based on partial input data. It helps users auto-complete and validate addresses efficiently by returning a list of suggested addresses that match the input criteria. This improves accuracy, increases speed, reduces errors, and streamlines the data entry process. Category: Address Validation Request body: line1 (string) - Primary address line, such as street name and number line2 (string) - Additional address details, such as an apartment or suite number line3 (string) - Additional address details for complex addresses city (string) - The city or town name for the address state (string) - State, province, or region of the address country (string) - Country code in ISO 3166-1 alpha-2 format (e.g., 'US' for the United States). Defaults to 'US'. should not be empty. Not validating here as the validation structure can be different for different providers postalCode (string) - ZIP or postal code for the address. Can be empty for some locales. Not validating here as the validation structure can be different for different providers id (integer) - Unique identifier for the request, if applicable county (string) - County or district name for the address fullAddress (string) - A complete address string that can be used as an alternative to providing individual fields. Response statuses: 200, 401, 422, 500 --- # Get customers GET /v1/customers Source: https://docs.trykintsugi.com/reference/get-customers GET /v1/customers Get customers The Get Customers API retrieves a paginated list of customers based on specified filters. This API allows searching, filtering by country and state, and sorting the results. Category: Customers Query parameters: search_query (string) - Search term to filter customers by name or other details country (CountryCodeEnum | string[]) - Country code in ISO 3166-1 alpha-2 format (e.g., 'US') allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state (string) - State or province code to filter customers source__in (string) - Filter customers by source (comma-separated) allowed values: SHOPIFY, API connection_id__in (string) - Filter customers by connection ID (comma-separated) allowed values: conn_abc123, conn_def456 order_by (string) - Comma-separated list of fields to sort results by. allowed values: created_at, street_1, street_2, city, state, postal_code, country, status page (integer) size (integer) Response fields: items (CustomerRead[], required) phone (string) - Customer's phone number street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields. name (string) - Name of the customer. external_id (string) - External identifier associated with the customer. status (StatusEnum) - Status of the customer. allowed values: ACTIVE, ARCHIVED email (string) - Customer's email address company_name (string) - Registered or legal business name of the customer. source (SourceEnum) - Source of the customer's record. allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) connection_id (string) - Identifier for the connection source, if applicable. [truncated, see the reference page] --- # Create customer POST /v1/customers Source: https://docs.trykintsugi.com/reference/create-customer POST /v1/customers Create customer The Create Customer API enables the creation of a new customer record with essential details like name, contact information, and address, along with optional metadata. Category: Customers Request body: phone (string) - Customer's phone number street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields. name (string) - Name of the customer. external_id (string) - External identifier associated with the customer. status (StatusEnum) - Status of the customer. allowed values: ACTIVE, ARCHIVED email (string) - Customer's email address company_name (string) - Registered or legal business name of the customer. source (SourceEnum) - Source of the customer's record. allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) connection_id (string) - Identifier for the connection source, if applicable. address_status (AddressStatus) - Status of address verification allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK registration_number (string) - Registration number of the customer. external_friendly_id (string) - External friendly identifier associated with the customer. We need it for netsuite. customer_tax_registrations (CustomerTaxRegistrationRead[]) - Customer tax registrations associated with the customer. id (string, required) customer_id (string, required) country_code (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) tax_type (CustomerTaxTypeEnum, required) - Enum for customer tax registration types. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown tax_id (string, required) [truncated, see the reference page] --- # Get customer by external id GET /v1/customers/external/{external_id} Source: https://docs.trykintsugi.com/reference/get-customer-by-external-id GET /v1/customers/external/{external_id} Get customer by external id The Get Customer By External ID API retrieves the details of a single customer using their external identifier. This endpoint is useful for accessing customer data when only an external ID is available. Category: Customers Path parameters: external_id (string, required) - The external identifier of the customer to retrieve. Response fields: phone (string) - Customer's phone number street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields. name (string) - Name of the customer. external_id (string) - External identifier associated with the customer. status (StatusEnum) - Status of the customer. allowed values: ACTIVE, ARCHIVED email (string) - Customer's email address company_name (string) - Registered or legal business name of the customer. source (SourceEnum) - Source of the customer's record. allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) connection_id (string) - Identifier for the connection source, if applicable. address_status (AddressStatus) - Status of address verification allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK registration_number (string) - Registration number of the customer. external_friendly_id (string) - External friendly identifier associated with the customer. We need it for netsuite. customer_tax_registrations (CustomerTaxRegistrationRead[]) - Customer tax registrations associated with the customer. id (string, required) customer_id (string, required) country_code (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) [truncated, see the reference page] --- # Get customer by id GET /v1/customers/{customer_id} Source: https://docs.trykintsugi.com/reference/get-customer-by-id GET /v1/customers/{customer_id} Get customer by id The Get Customer By ID API retrieves the details of a single customer using their unique identifier. It returns customer-specific data, including contact information, address, name and metadata, etc. Category: Customers Path parameters: customer_id (string, required) - Unique identifier of the customer Response fields: phone (string) - Customer's phone number street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields. name (string) - Name of the customer. external_id (string) - External identifier associated with the customer. status (StatusEnum) - Status of the customer. allowed values: ACTIVE, ARCHIVED email (string) - Customer's email address company_name (string) - Registered or legal business name of the customer. source (SourceEnum) - Source of the customer's record. allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) connection_id (string) - Identifier for the connection source, if applicable. address_status (AddressStatus) - Status of address verification allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK registration_number (string) - Registration number of the customer. external_friendly_id (string) - External friendly identifier associated with the customer. We need it for netsuite. customer_tax_registrations (CustomerTaxRegistrationRead[]) - Customer tax registrations associated with the customer. id (string, required) customer_id (string, required) country_code (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) [truncated, see the reference page] --- # Update customer PUT /v1/customers/{customer_id} Source: https://docs.trykintsugi.com/reference/update-customer PUT /v1/customers/{customer_id} Update customer The Update Customer API allows you to modify an existing customer's information using their unique identifier, enabling updates to their details as needed. Category: Customers Path parameters: customer_id (string, required) - Unique identifier of the customer to be retrieved. Request body: phone (string) - Phone number associated with the customer. street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) full_address (string) - Complete address string of the customer, which can be used as an alternative to individual fields. name (string) - Name of the customer. status (StatusEnum) - Status of the customer. allowed values: ACTIVE, ARCHIVED email (string) - Email address of the customer. company_name (string) - Registered or legal business name of the customer. source (SourceEnum) - Source of the customer's record allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) address_status (AddressStatus) - Address verification status. allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK external_id (string) - External identifier associated with the customer external_friendly_id (string) - External friendly identifier associated with the customer. We need it for netsuite. Response fields: phone (string) - Customer's phone number street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. country (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format [truncated, see the reference page] --- # Upsert customer tax registration POST /v1/customers/{customer_id}/tax-registrations Source: https://docs.trykintsugi.com/reference/upsert-customer-tax-registration POST /v1/customers/{customer_id}/tax-registrations Upsert customer tax registration Creates or updates a customer tax registration record. If a registration already exists for this customer with the same tax type and country code, it will be updated. Category: Customer Tax Registration Path parameters: customer_id (string, required) Request body: tax_id (string, required) Response fields: id (string, required) customer_id (string, required) country_code (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) tax_type (CustomerTaxTypeEnum, required) - Enum for customer tax registration types. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown tax_id (string, required) is_valid (boolean, required) Response statuses: 200, 422 --- # Get transactions by customer id GET /v1/customers/{customer_id}/transactions Source: https://docs.trykintsugi.com/reference/get-transactions-by-customer-id GET /v1/customers/{customer_id}/transactions Get transactions by customer id Get a list of transactions for a customer by their unique ID. When pagination params are provided, this endpoint returns a paginated response. When omitted, it returns the legacy list response format (deprecated). Category: Customers Path parameters: customer_id (string, required) Query parameters: page (integer) size (integer) Response fields: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (string) - Total amount of the transaction. [truncated, see the reference page] --- # Create transaction by customer id POST /v1/customers/{customer_id}/transactions Source: https://docs.trykintsugi.com/reference/create-transaction-by-customer-id POST /v1/customers/{customer_id}/transactions Create transaction by customer id Create a new transaction for a specific customer. Category: Customers Path parameters: customer_id (string, required) Request body: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (number | string) - Total amount of the transaction. customer_id (string) - Unique identifier of the customer. marketplace (boolean) - Indicates if transaction is marketplace-based. exempt (TransactionExemptStatusEnum) - Exemption status (e.g., NOT_EXEMPT) [truncated, see the reference page] --- # Get exemptions GET /v1/exemptions Source: https://docs.trykintsugi.com/reference/get-exemptions GET /v1/exemptions Get exemptions Retrieve a list of exemptions based on filters. Category: Exemptions Query parameters: search_query (string) - Search term to filter exemptions by exemption ID, customer name, or customer email status__in (string) - Filter exemptions by their status country_code (CountryCodeEnum | string[]) - Country code in ISO 3166-1 alpha-2 format allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) jurisdiction (string) - Jurisdiction identifier start_date (string) - Start date for filtering exemptions end_date (string) - End date for filtering exemptions customer_id (string) - Customer ID to filter exemptions transaction_id (string) - Transaction ID to filter exemptions connection_id__in (string) - Filter exemptions by customer connection ID (comma-separated) allowed values: conn_abc123, conn_def456 order_by (string) - Fields to sort by (comma-separated) page (integer) - Page number size (integer) - Page size Response fields: items (backend__src__exemptions__schemas__exemption__ExemptionRead[], required) exemption_type (ExemptionType, required) - The type of exemption (e.g., wholesale, resale) allowed values: customer, wholesale, transaction, reverse_charge, partial jurisdiction (string) - The jurisdiction identifier for the exemption country_code (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format (e.g., 'US') allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) start_date (string, required) - Start date for the exemption validity period (YYYY-MM-DD format) end_date (string) - End date for the exemption validity period (YYYY-MM-DD format) customer_id (string) - Unique identifier for the customer associated with the exemption transaction_id (string) - Unique identifier for the transaction associated with the exemption, if applicable. reseller (boolean) - Indicates whether the exemption is for a reseller FEIN (string) - Federal Employer Identification Number associated with the exemption. sales_tax_id (string) - Sales tax ID for the exemption status (ExemptionStatus) - The status of the exemption. Defaults to ACTIVE if not provided. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED id (string, required) customer_name (string) [truncated, see the reference page] --- # Create exemption POST /v1/exemptions Source: https://docs.trykintsugi.com/reference/create-exemption POST /v1/exemptions Create exemption The Create Exemption API allows you to create a new exemption record. This includes defining details such as exemption type, jurisdiction, Country, State, validity dates, etc. Category: Exemptions Request body: exemption_type (ExemptionType, required) - The type of exemption (e.g., wholesale, resale) allowed values: customer, wholesale, transaction, reverse_charge, partial jurisdiction (string) - The jurisdiction identifier for the exemption country_code (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format (e.g., 'US') allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) start_date (string, required) - Start date for the exemption validity period (YYYY-MM-DD format) end_date (string) - End date for the exemption validity period (YYYY-MM-DD format) customer_id (string, required) - Unique identifier for the customer associated with the exemption transaction_id (string) - Unique identifier for the transaction, if applicable reseller (boolean) - Indicates whether the exemption is for a reseller FEIN (string, required) - Federal Employer Identification Number sales_tax_id (string, required) - Sales tax ID for the exemption status (ExemptionStatus, required) - The status of the exemption allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED certificate_type (string) - Partial-exemption certificate form code. Required when exemption_type is partial; must be absent otherwise. Response fields: country_code (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format (e.g., 'US') allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) jurisdiction (string) - The jurisdiction identifier for the exemption start_date (string, required) - Start date for the exemption validity period (YYYY-MM-DD format) end_date (string) - End date for the exemption validity period (YYYY-MM-DD format) transaction_id (string) - Unique identifier for the transaction, if applicable reseller (boolean) - Indicates whether the exemption is for a reseller FEIN (string) - Federal Employer Identification Number sales_tax_id (string) - Sales tax ID for the exemption id (string, required) - Unique identifier for the exemption customer (CustomerRead) - Details of the customer associated with the exemption [truncated, see the reference page] --- # List partial certificate types GET /v1/exemptions/partial-certificate-types Source: https://docs.trykintsugi.com/reference/list-partial-certificate-types GET /v1/exemptions/partial-certificate-types List partial certificate types Certificate forms a partial exemption may use. Pass jurisdiction to limit the list to that state. Category: Exemptions Query parameters: jurisdiction (string) - Jurisdiction code. Only forms for this jurisdiction are returned. Response fields: code (string, required) name (string, required) jurisdiction (string, required) country (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) Response statuses: 200, 422 --- # Get exemption by id GET /v1/exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/get-exemption-by-id GET /v1/exemptions/{exemption_id} Get exemption by id The Get Exemption By ID API retrieves a specific exemption record by its unique ID. This API is useful for retrieving detailed information about a particular exemption, including its associated customer, organisation id, status, etc. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier for the exemption being retrieved. Response fields: exemption_type (ExemptionType, required) - The type of exemption (e.g., wholesale, resale) allowed values: customer, wholesale, transaction, reverse_charge, partial jurisdiction (string) - The jurisdiction identifier for the exemption country_code (CountryCodeEnum) - Country code in ISO 3166-1 alpha-2 format (e.g., 'US') allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) start_date (string, required) - Start date for the exemption validity period (YYYY-MM-DD format) end_date (string) - End date for the exemption validity period (YYYY-MM-DD format) customer_id (string) - Unique identifier for the customer associated with the exemption transaction_id (string) - Unique identifier for the transaction associated with the exemption, if applicable. reseller (boolean) - Indicates whether the exemption is for a reseller FEIN (string) - Federal Employer Identification Number associated with the exemption. sales_tax_id (string) - Sales tax ID for the exemption status (ExemptionStatus) - The status of the exemption. Defaults to ACTIVE if not provided. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED id (string, required) customer_name (string) attachment_id (string) certificate_type (string) Response statuses: 200, 404, 422, 500 --- # Get attachments for exemption GET /v1/exemptions/{exemption_id}/attachments Source: https://docs.trykintsugi.com/reference/get-attachments-for-exemption GET /v1/exemptions/{exemption_id}/attachments Get attachments for exemption The Get Attachments for Exemption API retrieves all attachments associated with a specific exemption. This is used to view and manage supporting documents like exemption certificates uploaded for a particular exemption record. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier for the exemption whose attachments are being retrieved. Response fields: related_entity_id (string, required) - The unique identifier of the exemption associated with the attachment. related_entity_type (RelatedEntityType, required) - The type of entity associated with the attachment. In this case, it will always be EXEMPTION, REGISTRATION ,FILING, FILING_PAYMENT. allowed values: EXEMPTION, REGISTRATION, FILING, FILING_PAYMENT, TASK id (string, required) - The unique identifier of the uploaded attachment (attachment ID). Response statuses: 200, 401, 422 --- # Upload exemption certificate POST /v1/exemptions/{exemption_id}/attachments Source: https://docs.trykintsugi.com/reference/upload-exemption-certificate POST /v1/exemptions/{exemption_id}/attachments Upload exemption certificate The Upload Exemption Certificate API allows you to upload a file attachment (e.g., exemption certificate) for a specific exemption. This is primarily used to associate supporting documents with an exemption record to ensure compliance and facilitate verification. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier for the exemption to which the attachment will be associated. Response fields: related_entity_id (string, required) - The unique identifier of the exemption associated with the attachment. related_entity_type (RelatedEntityType, required) - The type of entity associated with the attachment. In this case, it will always be EXEMPTION, REGISTRATION ,FILING, FILING_PAYMENT. allowed values: EXEMPTION, REGISTRATION, FILING, FILING_PAYMENT, TASK id (string, required) - The unique identifier of the uploaded attachment (attachment ID). Response statuses: 200, 401, 422, 500 --- # Get filings GET /v1/filings Source: https://docs.trykintsugi.com/reference/get-filings GET /v1/filings Get filings The Get Filings API retrieves a paginated list of filings based on filters such as dates, jurisdiction, Country, status, etc. This helps track and manage tax filings efficiently across multiple jurisdictions. Category: Filings Query parameters: status__in (string) - Filter filings by status allowed values: FILED, FILING, SUBMITTED, UNFILED, PAUSED, CANCELLED, ISSUE, SKIPPED start_date (string) - Filter filings with a start date greater than or equal to this date. end_date (string) - Filter filings with an end date less than or equal to this date. date_filed__gte (string) - Filter filings filed on or after this date. date_filed__lte (string) - Filter filings filed on or before this date. order_by (string) - Comma-separated list of fields to sort the results. allowed values: status, start_date, end_date, amount state_code (string) - Filter filings by state code (e.g., CA for California). country_code (CountryCodeEnum | string[]) - Filter filings by country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) filing_category__in (string) - Filter filings by category (e.g., REGULAR, BACK_FILING, AMENDMENT). tax_type__in (string) - Filter filings by tax type. Multiple tax types can be passed, separated by commas (SALES_TAX, USE_TAX, SALES_AND_USE_TAX). allowed values: SALES_TAX, USE_TAX page (integer) - Page number size (integer) - Page size Response fields: items (FilingRead[], required) status (FilingStatusEnum) - Filing status. Possible values: UNFILED, FILING, SUBMITTED, FILED, PAUSED, SKIPPED, CANCELLED, ISSUE. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE start_date (string, required) - The start date of the filing period. end_date (string, required) - The end date of the filing period. due_date (string) - The due date of the filing. date_filed (string) - The date the filing was completed, if applicable. is_manual (boolean) - Indicates if the filing was done manually. state_code (string) - The code of the state associated with the filing (e.g., IA, NY). state_name (string) - The name of the state associated with the filing (e.g., Iowa, New York). [truncated, see the reference page] --- # Create back filing request POST /v1/filings/back-filing-request Source: https://docs.trykintsugi.com/reference/create-back-filing-request POST /v1/filings/back-filing-request Create back filing request Create unapproved BACK_FILING rows for requested in-bounds periods. Category: Filings Request body: requests (BackFilingRequestRegistrationInput[], required) registration_id (string, required) periods (BackFilingRequestPeriodInput[], required) start_date (string, required) end_date (string, required) notes (string) Response fields: created_filings (FilingRead[], required) status (FilingStatusEnum) - Filing status. Possible values: UNFILED, FILING, SUBMITTED, FILED, PAUSED, SKIPPED, CANCELLED, ISSUE. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE start_date (string, required) - The start date of the filing period. end_date (string, required) - The end date of the filing period. due_date (string) - The due date of the filing. date_filed (string) - The date the filing was completed, if applicable. is_manual (boolean) - Indicates if the filing was done manually. state_code (string) - The code of the state associated with the filing (e.g., IA, NY). state_name (string) - The name of the state associated with the filing (e.g., Iowa, New York). country_code (CountryCodeEnum, required) - Country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) auto_approved (boolean) - Indicates if the filing was auto-approved. Defaults to false. paused_until_date (string) - Indicates the date when filing will be unpaused. assistance_ticket_id (string) - DevRev ticket DON for the active assistance-pause episode. Cleared when the filing is approved from PAUSED. filing_category (string) - Category of filing. Common values: REGULAR (standard periodic filing), BACK_FILING (past-due period), AMENDMENT (amended return). Prepayment is ``is_prepayment``, not a category. Different categories can have overlapping periods. is_prepayment (boolean) - True when this filing is a prepayment obligation. Independent of filing_category so a past-due prepayment can still be BACK_FILING. [truncated, see the reference page] --- # Get back filing request options GET /v1/filings/back-filing-request/options Source: https://docs.trykintsugi.com/reference/get-back-filing-request-options GET /v1/filings/back-filing-request/options Get back filing request options Eligible US registrations and periods for a customer back-filing request. Category: Filings Response fields: registrations (BackFilingRequestRegistrationOption[], required) registration_id (string, required) state_code (string, required) remittance_tag (string, required) periods (BackFilingRequestPeriod[], required) start_date (string, required) end_date (string, required) label (string, required) help_article_url (string, required) help_article_label (string, required) Response statuses: 200, 422 --- # Get current back filing terms GET /v1/filings/back-filing-terms/current Source: https://docs.trykintsugi.com/reference/get-current-back-filing-terms GET /v1/filings/back-filing-terms/current Get current back filing terms Current back filing terms shown before BACK_FILING approval. Category: Filings Response fields: id (string, required) version (integer, required) timeline (string, required) penalties_and_interest (string, required) what_you_are_approving (string, required) fees (string, required) help_article_url (string) help_article_label (string, required) Response statuses: 200, 422 --- # Get filings by registration id GET /v1/filings/registration/{registration_id} Source: https://docs.trykintsugi.com/reference/get-filings-by-registration-id GET /v1/filings/registration/{registration_id} Get filings by registration id The Get Filings By Registration ID API retrieves all filings associated with a specific registration ID. This allows users to query detailed filing information tied to a specific registration record. Category: Filings Path parameters: registration_id (string, required) - Unique identifier for the registration associated with the filings. Query parameters: page (integer) - Page number size (integer) - Page size Response fields: items (FilingRead[], required) status (FilingStatusEnum) - Filing status. Possible values: UNFILED, FILING, SUBMITTED, FILED, PAUSED, SKIPPED, CANCELLED, ISSUE. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE start_date (string, required) - The start date of the filing period. end_date (string, required) - The end date of the filing period. due_date (string) - The due date of the filing. date_filed (string) - The date the filing was completed, if applicable. is_manual (boolean) - Indicates if the filing was done manually. state_code (string) - The code of the state associated with the filing (e.g., IA, NY). state_name (string) - The name of the state associated with the filing (e.g., Iowa, New York). country_code (CountryCodeEnum, required) - Country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) auto_approved (boolean) - Indicates if the filing was auto-approved. Defaults to false. paused_until_date (string) - Indicates the date when filing will be unpaused. assistance_ticket_id (string) - DevRev ticket DON for the active assistance-pause episode. Cleared when the filing is approved from PAUSED. filing_category (string) - Category of filing. Common values: REGULAR (standard periodic filing), BACK_FILING (past-due period), AMENDMENT (amended return). Prepayment is ``is_prepayment``, not a category. Different categories can have overlapping periods. [truncated, see the reference page] --- # Get filing by id GET /v1/filings/{filing_id} Source: https://docs.trykintsugi.com/reference/get-filing-by-id GET /v1/filings/{filing_id} Get filing by id This API retrieves detailed information about a specific filing using its unique identifier (filing_id). Category: Filings Path parameters: filing_id (string, required) - Unique identifier for the filing to retrieve. Response fields: input_vat_recovery_rate (string) - Input VAT recovery rate applied to this filing, as a percentage 0-100. Null when no rate exists for the filing's country and year, which means fully recoverable. Uses the definitive rate when set, otherwise the year's frozen provisional. input_vat_recovery_rate_is_definitive (boolean) - True when input_vat_recovery_rate is this year's definitive rate. False when it is the provisional. Null when no rate exists. status (FilingStatusEnum) - Filing status. Possible values: UNFILED, FILING, SUBMITTED, FILED, PAUSED, SKIPPED, CANCELLED, ISSUE. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE start_date (string, required) - The start date of the filing period. end_date (string, required) - The end date of the filing period. due_date (string) - The due date of the filing. date_filed (string) - The date the filing was completed, if applicable. is_manual (boolean) - Indicates if the filing was done manually. state_code (string) - The code of the state associated with the filing (e.g., IA, NY). state_name (string) - The name of the state associated with the filing (e.g., Iowa, New York). country_code (CountryCodeEnum, required) - Country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) auto_approved (boolean) - Indicates if the filing was auto-approved. Defaults to false. paused_until_date (string) - Indicates the date when filing will be unpaused. assistance_ticket_id (string) - DevRev ticket DON for the active assistance-pause episode. Cleared when the filing is approved from PAUSED. filing_category (string) - Category of filing. Common values: REGULAR (standard periodic filing), BACK_FILING (past-due period), AMENDMENT (amended return). Prepayment is ``is_prepayment``, not a category. [truncated, see the reference page] --- # Approve filing PUT /v1/filings/{filing_id}/approve Source: https://docs.trykintsugi.com/reference/approve-filing PUT /v1/filings/{filing_id}/approve Approve filing Approve a specific filing by its ID. Category: Filings Path parameters: filing_id (string, required) Request body: back_filing_terms_id (string) back_filing_terms_accepted_at (string) request_id (string) Response fields: status (FilingStatusEnum) - Filing status. Possible values: UNFILED, FILING, SUBMITTED, FILED, PAUSED, SKIPPED, CANCELLED, ISSUE. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE start_date (string, required) - The start date of the filing period. end_date (string, required) - The end date of the filing period. due_date (string) - The due date of the filing. date_filed (string) - The date the filing was completed, if applicable. is_manual (boolean) - Indicates if the filing was done manually. state_code (string) - The code of the state associated with the filing (e.g., IA, NY). state_name (string) - The name of the state associated with the filing (e.g., Iowa, New York). country_code (CountryCodeEnum, required) - Country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) auto_approved (boolean) - Indicates if the filing was auto-approved. Defaults to false. paused_until_date (string) - Indicates the date when filing will be unpaused. assistance_ticket_id (string) - DevRev ticket DON for the active assistance-pause episode. Cleared when the filing is approved from PAUSED. filing_category (string) - Category of filing. Common values: REGULAR (standard periodic filing), BACK_FILING (past-due period), AMENDMENT (amended return). Prepayment is ``is_prepayment``, not a category. Different categories can have overlapping periods. is_prepayment (boolean) - True when this filing is a prepayment obligation. Independent of filing_category so a past-due prepayment can still be BACK_FILING. is_final (boolean) - True when this filing is a final return for deregistration. Independent of filing_category — finals stay REGULAR. approved_by (string) - User ID of who approved the filing. approved_at (string) - Timestamp when the filing was approved. [truncated, see the reference page] --- # Get nexus for org GET /v1/nexus Source: https://docs.trykintsugi.com/reference/get-nexus-for-org GET /v1/nexus Get nexus for org Get a list of all nexuses for the organization. Category: Nexus Query parameters: without_pagination (boolean) - Return all results without pagination disregard_view (string) - Filter nexuses by disregard view: 'exposed' or 'disregarded' search_query (string) - Search nexuses by state code or state name status__in (string) state_code (string) state_code__in (string) country_code__in (string) tax_type__in (string) order_by (string) collected_tax_nexus_met (boolean) page (integer) size (integer) Response fields: items (NexusResponse[], required) processing_status (NexusStatusEnum) allowed values: NEEDS_RERUN, UP_TO_DATE, NOT_READY status (NexusStateEnum) allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED country_code (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) state_name (string, required) treatment_of_exempt_transactions (TreatmentEnum, required) allowed values: INCLUDED, EXCLUDED, DEPENDS, INCLUDE_IF_PRESENCE, YES_SALES_NO_TRANSACTIONS trigger (string, required) sales_or_transactions (SalesOrTransactionsEnum, required) allowed values: EITHER, SALES, BOTH, TRANSACTIONS threshold_sales_bigint (integer) threshold_transactions (integer, required) start_date (string, required) transaction_count (integer) transactions_amount (string) previous_transaction_count (integer) - Deprecated: transaction_count now includes both current and previous period values when period_model is CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, or CURRENT_OR_PREVIOUS_12_MONTHS previous_transactions_amount (string) - Deprecated: transactions_amount now includes both current and previous period values when period_model is CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, or CURRENT_OR_PREVIOUS_12_MONTHS calculated_tax_liability (string) imported_tax_liability (string) tax_liability (string) nexus_met (boolean) nexus_met_date (string) tax_type (TaxTypeEnum) - Which tax obligation this nexus tracks. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE economic_nexus_met (boolean) economic_nexus_met_date (string) physical_nexus_met (boolean) physical_nexus_met_date (string) [truncated, see the reference page] --- # Get physical nexus GET /v1/nexus/physical_nexus Source: https://docs.trykintsugi.com/reference/get-physical-nexus GET /v1/nexus/physical_nexus Get physical nexus Retrieve a paginated list of physical nexuses for a specific organization. Category: Nexus Query parameters: page (integer) - Page number size (integer) - Page size country_code (string) state_code (string) order_by (string) Response fields: items (PhysicalNexusRead[], required) country_code (CountryCodeEnum, required) - The country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) - The state or province code in ISO 3166-2 format (e.g., CA). start_date (string, required) - The date when the nexus became effective (YYYY-MM-DD). end_date (string) - The date when the nexus ended, if applicable. category (PhysicalNexusCategory, required) - The reason for the nexus (e.g., 'TELECOMMUTING_OR_REMOTE_EMPLOYEE'). allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) external_id (string) - Optional external identifier for the nexus. source (PhysicalNexusSource) - The source of the physical nexus presence. Possible values: USER, DEEL. allowed values: USER, DEEL street_1 (string) - Primary street address for the physical presence location. street_2 (string) - Additional street address details, such as suite or unit number. city (string) - City of the physical presence location. postal_code (string) - ZIP or postal code of the physical presence location. id (string, required) - The unique identifier for the physical nexus. total (integer, required) page (integer, required) size (integer, required) pages (integer, required) Response statuses: 200, 401, 404, 422, 500 --- # Create physical nexus POST /v1/nexus/physical_nexus Source: https://docs.trykintsugi.com/reference/create-physical-nexus POST /v1/nexus/physical_nexus Create physical nexus The Create Physical Nexus API allows you to create a new physical nexus by specifying its attributes, including the location, start date, end date, etc. Category: Nexus Request body: country_code (CountryCodeEnum, required) - The country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) - The state or province code in ISO 3166-2 format (e.g., CA). start_date (string, required) - The date when the nexus became effective (YYYY-MM-DD). end_date (string) - The date when the nexus ended, if applicable. category (PhysicalNexusCategory, required) - The reason for the nexus (e.g., 'TELECOMMUTING_OR_REMOTE_EMPLOYEE'). allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) external_id (string) - Optional external identifier for the nexus. source (PhysicalNexusSource) - The source of the physical nexus presence. Possible values: USER, DEEL. allowed values: USER, DEEL street_1 (string) - Primary street address for the physical presence location. street_2 (string) - Additional street address details, such as suite or unit number. city (string) - City of the physical presence location. postal_code (string) - ZIP or postal code of the physical presence location. Response fields: country_code (CountryCodeEnum, required) - The country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) - The state or province code in ISO 3166-2 format (e.g., CA). [truncated, see the reference page] --- # Get physical nexus categories GET /v1/nexus/physical_nexus/categories Source: https://docs.trykintsugi.com/reference/get-physical-nexus-categories GET /v1/nexus/physical_nexus/categories Get physical nexus categories Get physical nexus categories Category: Nexus Query parameters: country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string) Response fields: name (string, required) title (string, required) description (string, required) example (string, required) is_category_assigned (boolean, required) Response statuses: 200, 422 --- # Update physical nexus PUT /v1/nexus/physical_nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/update-physical-nexus PUT /v1/nexus/physical_nexus/{physical_nexus_id} Update physical nexus The Update Physical Nexus API allows you to modify the details of an existing physical nexus by its unique ID. Category: Nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus to update. Request body: start_date (string, required) - The date when the nexus became effective (YYYY-MM-DD). end_date (string) - The date when the nexus ends, if applicable (YYYY-MM-DD). category (PhysicalNexusCategory, required) - The updated reason for the nexus, such as PHYSICAL_BUSINESS_LOCATION or TELECOMMUTING_OR_REMOTE_EMPLOYEE, etc. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) street_1 (string) - Primary street address for the physical presence location. street_2 (string) - Additional street address details, such as suite or unit number. city (string) - City of the physical presence location. postal_code (string) - ZIP or postal code of the physical presence location. Response fields: country_code (CountryCodeEnum, required) - The country code in ISO 3166-1 alpha-2 format (e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) - The state or province code in ISO 3166-2 format (e.g., CA). start_date (string, required) - The date when the nexus became effective (YYYY-MM-DD). end_date (string) - The date when the nexus ended, if applicable. category (PhysicalNexusCategory, required) - The reason for the nexus (e.g., 'TELECOMMUTING_OR_REMOTE_EMPLOYEE'). [truncated, see the reference page] --- # Delete physical nexus DELETE /v1/nexus/physical_nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/delete-physical-nexus DELETE /v1/nexus/physical_nexus/{physical_nexus_id} Delete physical nexus The Delete Physical Nexus API allows you to remove an existing physical nexus by its unique ID. Category: Nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus to delete. Response statuses: 200, 401, 404, 422, 500 --- # Get nexus details for id GET /v1/nexus/{nexus_id} Source: https://docs.trykintsugi.com/reference/get-nexus-details-for-id GET /v1/nexus/{nexus_id} Get nexus details for id Get details for a specific nexus by its ID. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Response fields: processing_status (NexusStatusEnum) allowed values: NEEDS_RERUN, UP_TO_DATE, NOT_READY status (NexusStateEnum) allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED country_code (CountryCodeEnum, required) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) state_name (string, required) treatment_of_exempt_transactions (TreatmentEnum, required) allowed values: INCLUDED, EXCLUDED, DEPENDS, INCLUDE_IF_PRESENCE, YES_SALES_NO_TRANSACTIONS trigger (string, required) sales_or_transactions (SalesOrTransactionsEnum, required) allowed values: EITHER, SALES, BOTH, TRANSACTIONS threshold_sales_bigint (integer) threshold_transactions (integer, required) start_date (string, required) transaction_count (integer) transactions_amount (string) previous_transaction_count (integer) - Deprecated: transaction_count now includes both current and previous period values when period_model is CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, or CURRENT_OR_PREVIOUS_12_MONTHS previous_transactions_amount (string) - Deprecated: transactions_amount now includes both current and previous period values when period_model is CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, or CURRENT_OR_PREVIOUS_12_MONTHS calculated_tax_liability (string) imported_tax_liability (string) tax_liability (string) nexus_met (boolean) nexus_met_date (string) tax_type (TaxTypeEnum) - Which tax obligation this nexus tracks. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE economic_nexus_met (boolean) economic_nexus_met_date (string) physical_nexus_met (boolean) physical_nexus_met_date (string) collected_tax_nexus_met (boolean) collected_tax_nexus_met_date (string) period_model (PeriodModelEnum, required) allowed values: CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, PRECEDING_YEAR_FROM_OCTOBER, CALENDAR_YEAR, PREVIOUS_12_MONTHS, CURRENT_OR_PREVIOUS_12_MONTHS, PREVIOUS_4_QUARTERS, PREVIOUS_4_QUARTERS_OFFSET, PRECEDING_YEAR, PRECEDING_YEAR_QUARTERLY, PRECEDING_YEAR_QUARTERLY_OFFSET period_start_date (string, required) [truncated, see the reference page] --- # Get products GET /v1/products Source: https://docs.trykintsugi.com/reference/get-products GET /v1/products Get products Retrieve a paginated list of products based on filters and search query. Category: Products Query parameters: query (string) - Search term to filter products by name or other details. status__in (string) - Filter products by status (comma-separated) product_category__in (string) - Filter products by category (comma-separated) product_subcategory__in (string) - Filter products by subcategory (comma-separated) source__in (string) - Filter products by source (comma-separated) connection_id__in (string) - Filter products by connection ID (comma-separated). Use __direct_api__ for products without a connection. order_by (string) - Order results by specified fields (comma-separated) page (integer) size (integer) Response fields: items (ProductRead[], required) id (string, required) external_id (string, required) sku (string[], required) code (string, required) name (string, required) description (string, required) status (ProductStatusEnum, required) allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED product_category (string, required) - Main category of the product. For example, Physical, Digital, etc. You can retrieve supported categories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) product_subcategory (string, required) - Subcategory of the product. For example, General Clothing, UNKNOWN, etc. You can retrieve supported subcategories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) tax_exempt (boolean, required) source (SourceEnum, required) allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) connection_id (string, required) classification_failed (boolean, required) store_name (string) source_taxonomy_type (string) source_taxonomy_code (string) source_taxonomy_id (string) source_taxonomy_name (string) source_taxonomy_categories (object[]) source_taxonomy_metadata (object) total (integer, required) page (integer, required) size (integer, required) pages (integer, required) Response statuses: 200, 401, 404, 422, 500 --- # Create product POST /v1/products Source: https://docs.trykintsugi.com/reference/create-product POST /v1/products Create product The Create Product API allows users to manually create a new product in the system. This includes specifying product details such as category, subcategory, and tax exemption status, etc. You can retrieve supported categories and subcategories from the [GET /products/categories endpoint](/reference/api/products/get-product-categories), or browse the full catalog with descriptions and examples in the [Product Categories guide](/docs/guides/product-categories). Idempotent on ``(organization_id, external_id, source)`` for connectionless creates (CP-4726): a re-POST of an existing identity returns ``200``. A live match is unchanged; a previously deleted match is revived (status returns to ``PENDING``). Use PUT to update fields. Category: Products Request body: external_id (string, required) - A unique external identifier for the product. name (string, required) - The name of the product. description (string) - A description of the product. status (ProductStatusEnum) - The approval status of the product. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED product_category (PublicProductCategoryEnum, required) - The high-level category of the product. allowed values: Physical, Digital, Misc, Services product_subcategory (ProductSubCategoryEnum | string, required) - The subcategory of the product. allowed values: UNKNOWN, SAAS, DIGITAL_GENERAL, B2B_SAAS, SOFTWARE_ON_PERSONAL_PROPERTY, SOFTWARE_DOWNLOADED, CUSTOM_SOFTWARE_ON_PERSONAL_PROPERTY, CUSTOM_SOFTWARE_DOWNLOADED, CUSTOMIZATION_OF_SOFTWARE, B2C_SAAS, IAAS, SERVICE_GENERAL (and 51 more, see the reference page) tax_exempt (boolean, required) - Specifies whether the product is tax-exempt. source (SourceEnum) - Indicates the source of the product. allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) Response fields: id (string, required) external_id (string, required) sku (string[], required) code (string, required) name (string, required) description (string, required) status (ProductStatusEnum, required) allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED product_category (string, required) - Main category of the product. For example, Physical, Digital, etc. You can [truncated, see the reference page] --- # Get product categories GET /v1/products/categories Source: https://docs.trykintsugi.com/reference/get-product-categories GET /v1/products/categories Get product categories The Get Product Categories API retrieves all product categories. This endpoint helps users understand and select the appropriate categories for their products. Category: Products Response fields: name (string, required) - Name of the product category (e.g., PHYSICAL, SERVICE, DIGITAL, MISCELLANEOUS) subcategories (ProductSubCategory[], required) - List of subcategories associated with the product category name (string, required) - Name of the product subcategory (e.g., ORAL_HYGIENE, MEDICAL_DEVICES, etc.) description (string, required) - Description of the subcategory in the context of sales tax example (string, required) - Example products or services within the subcategory is_frequent (boolean) - Indicates if the subcategory is a frequent subcategory used by the organization. This field is deprecated. Response statuses: 200, 401, 404, 422, 500 --- # Get product by id GET /v1/products/{product_id} Source: https://docs.trykintsugi.com/reference/get-product-by-id GET /v1/products/{product_id} Get product by id The Get Product By ID API retrieves detailed information about a single product by its unique ID. This API helps in viewing the specific details of a product, including its attributes, status, and categorization. Category: Products Path parameters: product_id (string, required) - The unique identifier for the product you want to retrieve. Response fields: id (string, required) external_id (string, required) sku (string[], required) code (string, required) name (string, required) description (string, required) status (ProductStatusEnum, required) allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED product_category (string, required) - Main category of the product. For example, Physical, Digital, etc. You can retrieve supported categories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) product_subcategory (string, required) - Subcategory of the product. For example, General Clothing, UNKNOWN, etc. You can retrieve supported subcategories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) tax_exempt (boolean, required) source (SourceEnum, required) allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) connection_id (string, required) classification_failed (boolean, required) store_name (string) source_taxonomy_type (string) source_taxonomy_code (string) source_taxonomy_id (string) source_taxonomy_name (string) source_taxonomy_categories (object[]) source_taxonomy_metadata (object) Response statuses: 200, 401, 404, 422, 500 --- # Update product PUT /v1/products/{product_id} Source: https://docs.trykintsugi.com/reference/update-product PUT /v1/products/{product_id} Update product The Update Product API allows users to modify the details of an existing product identified by its unique product_id. You can retrieve supported categories and subcategories from the [GET /products/categories endpoint](/reference/api/products/get-product-categories), or browse the full catalog with descriptions and examples in the [Product Categories guide](/docs/guides/product-categories) Category: Products Path parameters: product_id (string, required) - Unique identifier of the product to be updated. Request body: id (string) - The unique identifier of the product to be updated. external_id (string) - External identifier provided for the product, typically by the source system. sku (string[]) name (string, required) - Name of the product. description (string) - Description of the product. status (ProductStatusEnum) - The approval status of the product. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED product_category (string, required) - Main category of the product. For example, Physical, Digital, etc. You can retrieve supported categories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) product_subcategory (string, required) - Subcategory of the product. For example, General Clothing, UNKNOWN, etc. You can retrieve supported subcategories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) tax_exempt (boolean, required) - Indicates whether the product is tax-exempt. classification_failed (boolean) - Indicates if the product classification failed. Response fields: id (string, required) external_id (string, required) sku (string[], required) code (string, required) name (string, required) description (string, required) status (ProductStatusEnum, required) allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED product_category (string, required) - Main category of the product. For example, Physical, Digital, etc. You can retrieve supported categories from [GET /products/categories endpoint](/reference/api/products/get-product-categories) product_subcategory (string, required) - Subcategory of the product. For example, General Clothing, UNKNOWN, etc. You can [truncated, see the reference page] --- # Get registrations GET /v1/registrations Source: https://docs.trykintsugi.com/reference/get-registrations GET /v1/registrations Get registrations The Get Registrations API retrieves a paginated list of registrations. This API helps in tracking and managing registrations efficiently across multiple jurisdictions. Category: Registrations Query parameters: status__in (string) - Filter registrations by status. Multiple statuses can be passed, separated by commas. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED state_code (string) - Filter registrations by state code. filing_frequency__in (string) - Filter registrations by filing frequency. Multiple filing frequencies can be passed, separated by commas. country_code__in (CountryCodeEnum | string[]) - Filter registrations by country code in ISO 3166-1 alpha-2 format (e.g., US, CA). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) tax_type__in (string) - Filter registrations by tax type. Multiple tax types can be passed, separated by commas (SALES_TAX, USE_TAX, SALES_AND_USE_TAX). order_by (string) - Order results by specified fields (comma-separated) page (integer) - Page number size (integer) - Page size Response fields: items (RegistrationReadWithPassword[], required) registration_date (string) - The date when the registration was created. Format: YYYY-MM-DD. registration_email (string) - Email address associated with the registration. registration_requested (string) - Timestamp when the registration was requested. registration_completed (string) - Timestamp when the registration was completed. deregistration_requested (string) - Timestamp when deregistration was requested. deregistration_completed (string) - Timestamp when the deregistration was completed. auto_registered (boolean) - Indicates whether the registration was completed automatically. registrations_regime (RegistrationsRegimeEnum) - The tax registration regime (e.g., STANDARD, SIMPLIFIED). allowed values: STANDARD, SIMPLIFIED change_regime_status (ChangeRegimeStatusEnum) allowed values: REQUESTED, APPROVED, DONE, ACKNOWLEDGED third_party_enabled (boolean) - Indicates whether third-party access is enabled for this registration. do_not_file (boolean) - If true, do not file for this registration (treated as False by default). [truncated, see the reference page] --- # Create registration POST /v1/registrations Source: https://docs.trykintsugi.com/reference/create-registration POST /v1/registrations Create registration The Create Registration API allows users to create a new registration for tracking and managing tax filings efficiently across multiple jurisdictions. Category: Registrations Request body: registration_import_type (string) - Specifies this is a regular jurisdiction registration import. registration_date (string) - The date when the registration was created. Format: YYYY-MM-DD. registration_email (string) - Email address associated with the registration. registration_requested (string) - Timestamp when the registration was requested. registration_completed (string) - Timestamp when the registration was completed. deregistration_requested (string) - Timestamp when deregistration was requested. deregistration_completed (string) - Timestamp when the deregistration was completed. auto_registered (boolean) - Indicates whether the registration was completed automatically. do_not_file (boolean) - If true, do not file for this registration (treated as False by default). registrations_regime (RegistrationsRegimeEnum) - The tax registration regime (e.g., STANDARD, SIMPLIFIED). allowed values: STANDARD, SIMPLIFIED change_regime_status (ChangeRegimeStatusEnum) allowed values: REQUESTED, APPROVED, DONE, ACKNOWLEDGED is_pre_collecting (boolean) - Set true to mark the organization as collecting tax in this jurisdiction ahead of registration details, instead of a normal import. Opens the registration in PROCESSING; filing frequency and credentials are not required. country_code (CountryCodeEnum, required) - The country code (ISO 3166-1 alpha-2 format) where the registration applies. allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state_code (string, required) - The state/province code where the registration applies. state_name (string, required) - The name of the state/province. filing_frequency (FilingFrequencyEnum) - Specifies how often tax filings should be made. Possible values: MONTHLY, QUARTERLY, ANNUALLY, UNKNOWN. Required unless isPreCollecting is set. allowed values: UNKNOWN, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY, ANNUAL_FISCAL_YEAR, SEMI_MONTHLY, BI_MONTHLY, FOUR_MONTHLY, QUARTERLY_PREPAYMENT period_end_month (integer) - Fiscal-year anchor month (1-12) on which each recurring period [truncated, see the reference page] --- # Get jurisdiction specific fields GET /v1/registrations/jurisdiction-specific-fields Source: https://docs.trykintsugi.com/reference/get-jurisdiction-specific-fields GET /v1/registrations/jurisdiction-specific-fields Get jurisdiction specific fields Returns the JSON Schema and UI metadata for a state-specific registration form Category: Registrations Query parameters: country_code (string, required) - ISO 3166-1 alpha-2 country code (e.g., US). state_code (string, required) - State/province code (e.g., AL, LA). Response fields: country_code (string, required) state_code (string, required) default_form (boolean, required) - True when no state-specific schema exists and the generic form should be used. jurisdiction_fields_json_schema (object, required) - JSON Schema for the jurisdiction-specific fields, or empty dict when default_form is True. metadata (object, required) - UI metadata (help articles, portal URL, filing frequencies, etc.). Response statuses: 200, 422 --- # List registration jurisdictions GET /v1/registrations/jurisdictions Source: https://docs.trykintsugi.com/reference/list-registration-jurisdictions GET /v1/registrations/jurisdictions List registration jurisdictions Distinct registration jurisdictions (country + state) for filter dropdowns. Non-SST only. Default status__in matches GET /registrations (all statuses). Category: Registrations Query parameters: status__in (string) - Filter by registration status (comma-separated); same as GET /registrations. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED Response fields: country_code (string, required) - ISO 3166-1 alpha-2 country code (e.g. US, DE). state_code (string, required) - State or province code (may be empty for country-level rows). state_name (string, required) - Display name for the state or province. Response statuses: 200, 422 --- # Get registration by id GET /v1/registrations/{registration_id} Source: https://docs.trykintsugi.com/reference/get-registration-by-id GET /v1/registrations/{registration_id} Get registration by id The Get Registration By ID API retrieves a single registration record based on its unique identifier. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration to retrieve. Query parameters: reveal (string) - Name of field to reveal Response fields: registration_date (string) - The date when the registration was created. Format: YYYY-MM-DD. registration_email (string) - Email address associated with the registration. registration_requested (string) - Timestamp when the registration was requested. registration_completed (string) - Timestamp when the registration was completed. deregistration_requested (string) - Timestamp when deregistration was requested. deregistration_completed (string) - Timestamp when the deregistration was completed. auto_registered (boolean) - Indicates whether the registration was completed automatically. registrations_regime (RegistrationsRegimeEnum) - The tax registration regime (e.g., STANDARD, SIMPLIFIED). allowed values: STANDARD, SIMPLIFIED change_regime_status (ChangeRegimeStatusEnum) allowed values: REQUESTED, APPROVED, DONE, ACKNOWLEDGED third_party_enabled (boolean) - Indicates whether third-party access is enabled for this registration. do_not_file (boolean) - If true, do not file for this registration (treated as False by default). two_factor_enabled (boolean) - Indicates whether two-factor authentication (2FA) is enabled for this registration. marked_collecting (boolean) - Indicates whether the registration is marked as collecting in shopify is_pre_collecting (boolean) - True when this PROCESSING registration marks the organization as collecting tax in the jurisdiction ahead of registration details. It skips the Tax Ops registration task until the flag is cleared. status (RegistrationStatusEnum, required) - The current status of the registration. Possible values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED country_code (CountryCodeEnum, required) - The country code (ISO 3166-1 alpha-2 format) where the registration applies. [truncated, see the reference page] --- # Update registration PUT /v1/registrations/{registration_id} Source: https://docs.trykintsugi.com/reference/update-registration PUT /v1/registrations/{registration_id} Update registration The Update Registration API allows you to modify an existing registration using its unique registration_id. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration to be updated. Request body: registration_date (string) - The date when the registration was created. Format: YYYY-MM-DD. registration_email (string) - Email address associated with the registration. registration_requested (string) - Timestamp when the registration was requested. registration_completed (string) - Timestamp when the registration was completed. deregistration_requested (string) - Timestamp when deregistration was requested. deregistration_completed (string) - Timestamp when the deregistration was completed. auto_registered (boolean) - Indicates whether the registration was completed automatically. registrations_regime (RegistrationsRegimeEnum) - The tax registration regime (e.g., STANDARD, SIMPLIFIED). allowed values: STANDARD, SIMPLIFIED change_regime_status (ChangeRegimeStatusEnum) allowed values: REQUESTED, APPROVED, DONE, ACKNOWLEDGED third_party_enabled (boolean) - Indicates whether third-party access is enabled for this registration. do_not_file (boolean) - If true, do not file for this registration (treated as False by default). two_factor_enabled (boolean) - Indicates whether two-factor authentication (2FA) is enabled for this registration. marked_collecting (boolean) - Indicates whether the registration is marked as collecting in shopify is_pre_collecting (boolean) - True when this PROCESSING registration marks the organization as collecting tax in the jurisdiction ahead of registration details. It skips the Tax Ops registration task until the flag is cleared. encrypted_username (string) - The encrypted username for the registration. username (string) - The username associated with the registration. filing_frequency (FilingFrequencyEnum) - The updated filing frequency (MONTHLY, QUARTERLY, etc.). allowed values: UNKNOWN, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY, ANNUAL_FISCAL_YEAR, SEMI_MONTHLY, BI_MONTHLY, FOUR_MONTHLY, QUARTERLY_PREPAYMENT create_filings_from (string) - The updated date from which filings should start (YYYY-MM-DD). [truncated, see the reference page] --- # Upload registration attachment POST /v1/registrations/{registration_id}/attachments Source: https://docs.trykintsugi.com/reference/upload-registration-attachment POST /v1/registrations/{registration_id}/attachments Upload registration attachment Upload an attachment for a specific registration. Category: Registrations Path parameters: registration_id (string, required) Response fields: id (string) created_at (string) - Timestamp when transaction was created in Kintsugi. updated_at (string) - Timestamp when transaction was last updated. related_entity_id (string, required) - The unique identifier of the exemption associated with the attachment. related_entity_type (RelatedEntityType, required) - The type of entity associated with the attachment. In this case, it will always be EXEMPTION, REGISTRATION ,FILING, FILING_PAYMENT. allowed values: EXEMPTION, REGISTRATION, FILING, FILING_PAYMENT, TASK organization_id (string, required) file_name (string, required) mime_type (string, required) file_size_bytes (integer, required) file_location (string, required) file_location_type (AttachmentLocationType, required) allowed values: S3, LOCAL Response statuses: 200, 422 --- # Deregister registration POST /v1/registrations/{registration_id}/deregister Source: https://docs.trykintsugi.com/reference/deregister-registration POST /v1/registrations/{registration_id}/deregister Deregister registration Deregister an existing registration. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration to deregister. Request body: closure_date (string, required) - Effective date the permit closes with the jurisdiction (YYYY-MM-DD). Past and future dates are accepted. reason (DeregistrationReasonEnum, required) - Why the permit is closing: full business closure, or closing nexus in this one state. allowed values: FULL_BUSINESS_CLOSURE, CLOSING_NEXUS_IN_STATE final_return_acknowledged (boolean, required) - Must be true: the actor confirms a final return is still owed. request_id (string) - Optional client-minted id for this confirm attempt. Response fields: registration_date (string) - The date when the registration was created. Format: YYYY-MM-DD. registration_email (string) - Email address associated with the registration. registration_requested (string) - Timestamp when the registration was requested. registration_completed (string) - Timestamp when the registration was completed. deregistration_requested (string) - Timestamp when deregistration was requested. deregistration_completed (string) - Timestamp when the deregistration was completed. auto_registered (boolean) - Indicates whether the registration was completed automatically. registrations_regime (RegistrationsRegimeEnum) - The tax registration regime (e.g., STANDARD, SIMPLIFIED). allowed values: STANDARD, SIMPLIFIED change_regime_status (ChangeRegimeStatusEnum) allowed values: REQUESTED, APPROVED, DONE, ACKNOWLEDGED third_party_enabled (boolean) - Indicates whether third-party access is enabled for this registration. do_not_file (boolean) - If true, do not file for this registration (treated as False by default). two_factor_enabled (boolean) - Indicates whether two-factor authentication (2FA) is enabled for this registration. marked_collecting (boolean) - Indicates whether the registration is marked as collecting in shopify is_pre_collecting (boolean) - True when this PROCESSING registration marks the organization as collecting tax in the jurisdiction ahead of registration details. It skips the Tax Ops registration task until the flag is cleared. [truncated, see the reference page] --- # Get oss countries for registration GET /v1/registrations/{registration_id}/oss-countries Source: https://docs.trykintsugi.com/reference/get-oss-countries-for-registration GET /v1/registrations/{registration_id}/oss-countries Get oss countries for registration Get all OSS countries for a specific registration. This endpoint returns a list of EU countries that are covered by the OSS registration. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: id (string, required) - The unique identifier for the OSS registration country. country_code (CountryCodeEnum, required) - The EU country code covered by the OSS registration. allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) effective_date (string, required) - The date from which this country is officially covered by the OSS registration. end_date (string) - The date this country ceased to be covered by the OSS registration (if applicable). status (OssCountryStatusEnum, required) - The current status of this country's enrollment in the OSS registration. allowed values: ACTIVE, REMOVED Response statuses: 200, 422 --- # Estimate tax POST /v1/tax/estimate Source: https://docs.trykintsugi.com/reference/estimate-tax POST /v1/tax/estimate Estimate tax The Estimate Tax API calculates the estimated tax for a specific transaction based on the provided details, including organization nexus, transaction details, customer details, and addresses. Optionally simulates nexus being met for tax calculation purposes. The `simulate_nexus_met` parameter is deprecated and will be removed in future releases. Category: Tax Estimation Query parameters: simulate_nexus_met (boolean) - **Deprecated:** Use `simulate_active_registration` in the request body instead. Request body: date (string, required) - The date of the transaction in ISO 8601 format (e.g., 2025-01-25T12:00:00Z). external_id (string, required) - Unique identifier of this transaction in the source system. currency (CurrencyEnum, required) - The currency in which the transaction is conducted (e.g., USD, EUR). allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) description (string) - An optional description of the transaction. source (SourceEnum) - While currently not used, it may be used in the future to determine taxability. The source of the transaction (e.g., OTHER). allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) marketplace (boolean) - Indicates if the transaction involves a marketplace. transaction_items (TransactionItemEstimateBase[], required) - List of items involved in the transaction. external_id (string) - A unique identifier for the transaction item. date (string, required) - The date of the transaction item. description (string) - A description of the item. external_product_id (string) - External product identifier. If not found and product_subcategory and product_category are not provided, an error occurs. product_name (string) - Name of the product. Used if creating a new product. product_description (string) - Description of the product. Used if creating a new product. product_source (SourceEnum) allowed values: BIGCOMMERCE, BESTBUY, BUNNY, CHARGEBEE, SHOPIFY, SHOPLINE, ECWID, STRIPE, AMAZON, TIKTOK, CUSTOM, UNKNOWN (and 66 more, see the reference page) product_subcategory (string) - Subcategory of the product. Required if product_category is used in place of external_product_id. [truncated, see the reference page] --- # Get transactions GET /v1/transactions Source: https://docs.trykintsugi.com/reference/get-transactions GET /v1/transactions Get transactions The Get Transactions API retrieves a list of transactions with optional filtering, sorting, and pagination. Category: Transactions Query parameters: state_code (string) - Filter transactions by state code. transaction_type (string) - Filter by transaction type (e.g., SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, ARCHIVE etc.). transaction_source (string) - Filter transactions based on the source. search_query (string) - Search for transactions using a general query (e.g., order ID, customer name). country (CountryCodeEnum | string[]) - Filter transactions by country code (ISO 3166-1 alpha-2 format, e.g., US). allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) state (string) - Filter by full state name (e.g., California). address_status__in (string) - Filter by address status (e.g., UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE). status (TransactionStatusEnum) - Filter by transaction status (e.g., PENDING, COMMITTED, CANCELLED, ARCHIVED). For refund filtering use the refund_status parameter. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID, ARCHIVED refund_status (TransactionRefundStatus) - Filter by refund status (e.g., FULLY_REFUNDED, PARTIALLY_REFUNDED). allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED filing_id (string) - Retrieve transactions linked to a specific filing ID. order_by (string) - Sort results based on specified fields. Prefix with - for descending order (e.g., -date for newest first). date__gte (string) - Retrieve transactions with a date greater than or equal to the bound (YYYY-MM-DD or ISO datetime in UTC). Defaults to 12 months ago when neither date__gte nor date__lte is provided. date__lte (string) - Retrieve transactions with a date less than or equal to the bound (YYYY-MM-DD or ISO datetime in UTC). processing_status__in (string) - Filter transactions based on processing status. Multiple values can be passed as a comma-separated list. marketplace (boolean) - Filter transactions by marketplace (e.g., AMAZON, EBAY). exempt__in (string) - Filter transactions by exemption status. Multiple values can be passed as a comma-separated list (e.g., EXEMPT,TAXABLE). [truncated, see the reference page] --- # Create transaction POST /v1/transactions Source: https://docs.trykintsugi.com/reference/create-transaction POST /v1/transactions Create transaction Create a transaction. Set `marketplace: true` for reseller or marketplace orders where tax was remitted externally; gross sales still count toward nexus, but tax liability is excluded. Category: Transactions Request body: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (number | string) - Total amount of the transaction. customer_id (string) - Unique identifier of the customer. marketplace (boolean) - Indicates if transaction is marketplace-based. [truncated, see the reference page] --- # Archive transaction by id POST /v1/transactions/archive Source: https://docs.trykintsugi.com/reference/archive-transaction-by-id POST /v1/transactions/archive Archive transaction by id Archive transactions by transaction id Category: Transactions Query parameters: transaction_id (string, required) Response statuses: 200, 422 --- # Get transaction by external id GET /v1/transactions/external/{external_id} Source: https://docs.trykintsugi.com/reference/get-transaction-by-external-id GET /v1/transactions/external/{external_id} Get transaction by external id Retrieves a specific transaction based on its external ID. This allows users to fetch transaction details using an identifier from an external system. Category: Transactions Path parameters: external_id (string, required) - The unique external identifier of the transaction. Response fields: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (string) - Total amount of the transaction. customer_id (string) - Unique identifier of the customer. [truncated, see the reference page] --- # Get transactions by filing id GET /v1/transactions/filings/{filing_id} Source: https://docs.trykintsugi.com/reference/get-transactions-by-filing-id GET /v1/transactions/filings/{filing_id} Get transactions by filing id Retrieve transactions by filing ID. Category: Transactions Path parameters: filing_id (string, required) - The unique identifier of the filing whose transactions you wish to retrieve. Response fields: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (string) - Total amount of the transaction. customer_id (string) - Unique identifier of the customer. marketplace (boolean) - Indicates if transaction is marketplace-based. [truncated, see the reference page] --- # Create credit note by transaction id POST /v1/transactions/{original_transaction_id}/credit_notes Source: https://docs.trykintsugi.com/reference/create-credit-note-by-transaction-id POST /v1/transactions/{original_transaction_id}/credit_notes Create credit note by transaction id Create a new credit note for a specific transaction. Idempotent on ``(organization_id, connection_id, source, external_id)`` for the same parent: a re-POST returns ``200`` with the stored credit note unchanged. The same external id against a different parent still conflicts. Use PUT to update fields. Category: Transactions Path parameters: original_transaction_id (string, required) Request body: external_id (string, required) - Unique identifier for the credit note in the external system. external_friendly_id (string) - Human-readable identifier for the credit note, often used for display purposes. secondary_external_id (string) - Secondary external identifier, reserved for marketplace/channel source ids (paired with secondary_source). date (string, required) - Date when the credit note was issued or created. status (string, required) - Current state of the credit note in its lifecycle. allowed values: PENDING, CANCELLED, COMMITTED description (string) - Brief explanation or reason for issuing the credit note. total_amount (number | string, required) - Total monetary value of the credit note, including all items and taxes. marketplace (boolean) - Indicates whether this credit note is associated with a marketplace transaction. tax_amount_imported (number | string) - Pre-calculated total tax amount for the entire credit note, if provided by the external system. tax_rate_imported (number | string) - Pre-calculated overall tax rate for the credit note, if provided by the external system. taxable_amount (number | string) - Total portion of the credit note amount subject to taxation. currency (CurrencyEnum, required) - The currency used for all amounts in this credit note. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) addresses (TransactionAddressBuilder[]) - A list of TransactionAddressBuilder objects or None if no addresses are provided. This field represents the addresses associated with the transaction. phone (string) - Phone number associated with the address. street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. [truncated, see the reference page] --- # Update credit note by transaction id PUT /v1/transactions/{original_transaction_id}/credit_notes/{credit_note_id} Source: https://docs.trykintsugi.com/reference/update-credit-note-by-transaction-id PUT /v1/transactions/{original_transaction_id}/credit_notes/{credit_note_id} Update credit note by transaction id Update an existing credit note for a specific transaction. Category: Transactions Path parameters: original_transaction_id (string, required) credit_note_id (string, required) Request body: external_id (string, required) - Unique identifier for the credit note in the external system. external_friendly_id (string) - Human-readable identifier for the credit note, often used for display purposes. secondary_external_id (string) - Secondary external identifier, reserved for marketplace/channel source ids (paired with secondary_source). date (string, required) - Date when the credit note was issued or created. status (string, required) - Current state of the credit note in its lifecycle. allowed values: PENDING, CANCELLED, COMMITTED description (string) - Brief explanation or reason for issuing the credit note. total_amount (number | string, required) - Total monetary value of the credit note, including all items and taxes. marketplace (boolean) - Indicates whether this credit note is associated with a marketplace transaction. tax_amount_imported (number | string) - Pre-calculated total tax amount for the entire credit note, if provided by the external system. tax_rate_imported (number | string) - Pre-calculated overall tax rate for the credit note, if provided by the external system. taxable_amount (number | string) - Total portion of the credit note amount subject to taxation. currency (CurrencyEnum, required) - The currency used for all amounts in this credit note. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) addresses (TransactionAddressBuilder[]) - A list of TransactionAddressBuilder objects or None if no addresses are provided. This field represents the addresses associated with the transaction. phone (string) - Phone number associated with the address. street_1 (string) - Primary street address. street_2 (string) - Additional street address details, such as an apartment or suite number. city (string) - City where the customer resides. county (string) - County or district of the customer. state (string) - State or province of the customer. postal_code (string) - ZIP or Postal code of the customer. [truncated, see the reference page] --- # Get transaction by id GET /v1/transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/get-transaction-by-id GET /v1/transactions/{transaction_id} Get transaction by id The Get Transaction By Id API retrieves detailed information about a specific transaction by providing its unique transaction ID. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to retrieve. Response fields: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (string) - Total amount of the transaction. customer_id (string) - Unique identifier of the customer. [truncated, see the reference page] --- # Update transaction PUT /v1/transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/update-transaction PUT /v1/transactions/{transaction_id} Update transaction Update a specific transaction by its ID. Category: Transactions Path parameters: transaction_id (string, required) Request body: requires_exemption (ExemptionRequired) - Indicates if transaction requires tax exemption. jurisdiction (string) customer_id (string) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. exemption_type (ExemptionType, required) - Type of exemption. `partial` is not accepted here because it needs a certificate form; add partial exemptions to the customer instead. allowed values: customer, wholesale, transaction, reverse_charge, partial start_date (string, required) status (ExemptionStatus, required) allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED reseller (boolean, required) country_code (CountryCodeEnum) allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) end_date (string) FEIN (string) sales_tax_id (string) source (ExemptionSourceEnum) - Source of exemption, needs extension for new sources which supports multi-state exemptions allowed values: NETSUITE, QUICKBOOKS, INTUIT_ENTERPRISE_SUITE, SAGE_INTACCT, SHOPIFY, XERO, STRIPE, BIGCOMMERCE, MAGENTO, MAXIO, CHARGEBEE, ZUORA (and 14 more, see the reference page) organization_id (string, required) - Unique identifier of the organization. This field is deprecated, and should no longer be used. The value is populated through the 'x-organization-id' header. external_id (string, required) - External identifier of the transaction. date (string, required) - Transaction date and time shop_date (string) - Transaction date in the shop's local timezone shop_date_tz (string) - Timezone of the shop description (string) - Description of the transaction. refund_status (TransactionRefundStatus) - Status of refund, if applicable allowed values: FULLY_REFUNDED, PARTIALLY_REFUNDED total_amount (number | string) - Total amount of the transaction. customer_id (string) - Unique identifier of the customer. marketplace (boolean) - Indicates if transaction is marketplace-based. exempt (TransactionExemptStatusEnum) - Exemption status (e.g., NOT_EXEMPT) [truncated, see the reference page] --- # Set transaction tax only POST /v1/transactions/{transaction_id}/tax_only Source: https://docs.trykintsugi.com/reference/set-transaction-tax-only POST /v1/transactions/{transaction_id}/tax_only Set transaction tax only Mark or unmark a transaction as tax-only. SALE becomes TAX_COLLECTION; credit notes become TAX_REFUND. Unmark restores SALE or re-derives FULL/PARTIAL credit note. Only the type is changed; amounts are preserved. Category: Transactions Path parameters: transaction_id (string, required) Request body: tax_only (boolean, required) - True to mark as tax-only; false to remove the tax-only marking. Response statuses: 204, 422 --- # Preview addresses eligible for batch approval GET /addresses/approval-preview Source: https://docs.trykintsugi.com/reference/2026-10-06/preview-addresses-eligible-for-batch-approval GET /addresses/approval-preview Preview addresses eligible for batch approval Preview the addresses a batch approval would cover across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `status` (comma-separated, default `INVALID,BLANK`) chooses which statuses are eligible, and `limit` caps the returned `addresses` page; `totalEligible` is the full count regardless of `limit`. The same `country`, `has*` and `addressNotEmpty` filters as the summary apply. Category: Addresses Query parameters: status (string) - Comma-separated address statuses to treat as eligible; defaults to `INVALID,BLANK`. limit (integer) - Maximum number of addresses to return in the preview page. country (string) - ISO-3166 alpha-2 country code to filter by. hasCountry (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a country. hasState (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a state. hasCity (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a city. hasCounty (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a county. hasPostalCode (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a postal code. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: totalEligible (integer, required) - Total addresses eligible for approval under the requested filters. addresses (TransactionAddress[], required) - First page of eligible addresses, capped by `limit`. `totalEligible` is the full count regardless of this cap. id (string, required) - Identifier for the address. type (PublicAddressTypeEnum, required) - Which party or location this address represents. Tax jurisdiction usually follows `SHIP_TO` (or `BILL_TO` when there is no ship-to). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. [truncated, see the reference page] --- # Batch-approve addresses POST /addresses/approve Source: https://docs.trykintsugi.com/reference/2026-10-06/batch-approve-addresses POST /addresses/approve Batch-approve addresses Mark a set of addresses verified and requeue their transactions for tax recalculation, for one organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to name it. Choose the set with `addressIds` OR `filters`, exactly one. `status` limits which verification statuses are eligible (default `INVALID,BLANK`) and `limit` caps how many are approved. An already-verified address is skipped, not re-approved. Any member of the organization, a partner Owner/Admin or an API key for the organization may approve. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Request body: addressIds (string[]) - Ids of the addresses to approve. Send this or `filters`, not both. `null` when selecting by `filters` instead. filters (AddressApproveFilters) - Filter selecting the addresses to approve. Send this or `addressIds`, not both. `null` when selecting by `addressIds` instead. countryCode (string) - ISO 3166-1 alpha-2 country code to filter by, such as `US`, `CA` or `GB`. Omit to not filter by country. hasCountry (boolean) - Keep addresses that do (`true`) or do not (`false`) have a country. Omit to not filter on this. hasState (boolean) - Keep addresses that do (`true`) or do not (`false`) have a state. Omit to not filter on this. hasCity (boolean) - Keep addresses that do (`true`) or do not (`false`) have a city. Omit to not filter on this. hasCounty (boolean) - Keep addresses that do (`true`) or do not (`false`) have a county. Omit to not filter on this. hasPostalCode (boolean) - Keep addresses that do (`true`) or do not (`false`) have a postal code. Omit to not filter on this. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. status (ApprovableAddressStatus[]) - Verification statuses eligible for approval; an address outside this set is skipped. Only `INVALID` and `BLANK` may be approved, and both are the default. allowed values: INVALID, BLANK limit (integer) - Maximum number of addresses to approve in this request. Response fields: approvedCount (integer, required) - Number of addresses this request marked verified. [truncated, see the reference page] --- # Suggest a fill for one blank address GET /addresses/blank-suggestion Source: https://docs.trykintsugi.com/reference/2026-10-06/suggest-a-fill-for-one-blank-address GET /addresses/blank-suggestion Suggest a fill for one blank address Suggest a postal code, city, state and country for one blank address, chosen from the organization's most common verified address. A preview only: apply it with `PATCH /transactions/{transactionId}/addresses`. Searched across every organization your credential owns. Returns 400 if the address already has a postal code, city and state, and 404 if the address does not exist, is not owned, or no valid address exists to suggest from. Category: Addresses Query parameters: addressId (string, required) - The blank address to suggest a fill for. Response fields: addressId (string, required) - The blank address this suggestion is for. city (string) - City or locality. An empty string when none was supplied. state (string) - Suggested state or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - Suggested ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Assign the business address to blank transactions POST /addresses/bulk-assign-business-address Source: https://docs.trykintsugi.com/reference/2026-10-06/assign-the-business-address-to-blank-transactions POST /addresses/bulk-assign-business-address Assign the business address to blank transactions Assign the organization's own business address to its selected blank-address transactions and re-queue validation. Ids that are not (or no longer) blank-eligible are ignored and reported. `certified` must be `true`. Returns `businessAddressMissing: true` (assigning nothing) when the organization has no business address configured. Any member of the organization, a partner Owner/Admin or an API key for the organization may assign. A partner Member gets 403, you get 404 if you do not own the organization, and 400 if `certified` is not set. Category: Addresses Request body: transactionIds (string[], required) - Ids of the blank-address transactions to assign the business address to. certified (boolean) - Must be `true` to certify the assignment; the request is rejected otherwise. Response fields: updated (integer, required) - Transactions the business address was assigned to. skippedNoBusinessAddress (integer, required) - Eligible transactions skipped because the organization has no business address configured. failed (integer, required) - Transactions whose address write failed. ignored (integer, required) - Requested transactions dropped because they were not (or no longer) blank-eligible. businessAddressMissing (boolean, required) - `true` when the organization has no business address configured, so nothing was assigned. Set one and retry. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Fill the organization's blank-address transactions POST /addresses/fill-blank Source: https://docs.trykintsugi.com/reference/2026-10-06/fill-the-organization-s-blank-address-transactions POST /addresses/fill-blank Fill the organization's blank-address transactions Queue a fill for every blank-address transaction in the resolved organization, assigning each a most-likely address inferred from the organization's own verified addresses, and re-queue it for tax recalculation. `queued` is `false` when the organization has no blank-address transactions to fill. Any member of the organization, a partner Owner/Admin or an API key for the organization may run it. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Response fields: queued (boolean, required) - Whether a fill job was queued. `false` when the organization had no blank-address transactions to fill. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Count addresses needing attention GET /addresses/needs-attention-summary Source: https://docs.trykintsugi.com/reference/2026-10-06/count-addresses-needing-attention GET /addresses/needs-attention-summary Count addresses needing attention Count the addresses needing attention (invalid and blank) across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. These match the review dashboard, which counts committed transactions with an address problem rather than raw address rows, so they can differ from `byStatus` on the summary. Category: Addresses Response fields: invalid (integer, required) - Transactions in scope with an invalid address. blank (integer, required) - Transactions in scope with a blank address. needsAttentionTotal (integer, required) - Sum of `invalid` and `blank`. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Re-queue invalid-address transactions for validation PUT /addresses/revalidation Source: https://docs.trykintsugi.com/reference/2026-10-06/re-queue-invalid-address-transactions-for-validation PUT /addresses/revalidation Re-queue invalid-address transactions for validation Re-queue the invalid-address transactions matching the given filters (the same `country`/`countryIn`, `has*`, `addressNotEmpty` and `searchQuery` filters as the review list) in one organization for address validation, returning how many were re-queued. Any member of the organization, a partner Owner/Admin or an API key for the organization may run it. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Query parameters: searchQuery (string) - Free-text search over the invalid-address transactions to re-queue. countryIn (string) - Comma-separated ISO-3166 alpha-2 country codes to filter by; the `EU` placeholder expands to the EU member states. Overrides `country`. country (string) - ISO-3166 alpha-2 country code to filter by. hasCountry (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a country. hasState (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a state. hasCity (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a city. hasCounty (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a county. hasPostalCode (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a postal code. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: revalidatedCount (integer, required) - Number of invalid-address transactions re-queued for validation. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Suggest addresses for a partial input POST /addresses/suggestions Source: https://docs.trykintsugi.com/reference/2026-10-06/suggest-addresses-for-a-partial-input POST /addresses/suggestions Suggest addresses for a partial input Return a list of suggested addresses that match a partial or ambiguous input, to power address autocomplete. The list is empty when there are no matches. Returns 400 if the country is not supported, and 503 if the address validation service is temporarily unavailable. Category: Addresses Request body: street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. fullAddress (string) - Single-line full address, as an alternative to fields. Response fields: city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province of the suggested address. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - ISO 3166-1 alpha-2 country code of the suggestion, such as `US`, `CA` or `GB`. Response statuses: 200, 400, 401, 403, 404, 409, 422, 503 --- # Suggest addresses for many inputs POST /addresses/suggestions/bulk Source: https://docs.trykintsugi.com/reference/2026-10-06/suggest-addresses-for-many-inputs POST /addresses/suggestions/bulk Suggest addresses for many inputs Return suggestions for a batch of addresses in one request, one group per input correlated by the `id` you send. Every input always comes back as a group, in request order; a group has an empty `suggestions` list when there are no matches, the country is unsupported, or the validation service was unavailable for it. Category: Addresses Request body: addresses (BulkAddressSuggestionsItem[], required) - The addresses to fetch suggestions for. id (string) - Your identifier, echoed on the response group. connectionId (string) - Connection this address belongs to, used to resolve a default country. street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. fullAddress (string) - Single-line full address, as an alternative to fields. Response fields: id (string) - The `id` from the matching request address; empty if none was sent. suggestions (AddressSuggestion[], required) - Suggested addresses for this input; empty when there are none. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province of the suggested address. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - ISO 3166-1 alpha-2 country code of the suggestion, such as `US`, `CA` or `GB`. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Summarize addresses by verification status GET /addresses/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-addresses-by-verification-status GET /addresses/summary Summarize addresses by verification status Count addresses by verification status across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Filter the counted set with `country`, the `has*` presence filters and `addressNotEmpty`, and with `addressType`. `total` is the sum of `byStatus`. Category: Addresses Query parameters: addressType (PublicAddressTypeEnum) - Address role to filter by (e.g. `SHIP_TO`). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM country (string) - ISO-3166 alpha-2 country code to filter by. hasCountry (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a country. hasState (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a state. hasCity (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a city. hasCounty (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a county. hasPostalCode (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a postal code. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: total (integer, required) - Total addresses in scope, the sum of `byStatus`. byStatus (AddressStatusCount[], required) - One entry per status present in scope. A status with no addresses is omitted rather than reported as zero. status (PublicAddressStatusEnum, required) - The verification status this count is for. allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK count (integer, required) - Number of addresses in scope with this status. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Update transaction addresses in a batch PUT /addresses/transactions Source: https://docs.trykintsugi.com/reference/2026-10-06/update-transaction-addresses-in-a-batch PUT /addresses/transactions Update transaction addresses in a batch Update the addresses on a batch of transactions in one organization. Identify each address by `id`, or omit `id` and identify it by `transactionId` + `type` to upsert. Setting an address resets its transaction and re-queues address validation. Returns one `UPDATED`/`FAILED` result per input address, in request order; an upsert's result has a null `addressId`. `isUnincorporated` is optional and left unchanged when omitted. Any member of the organization, a partner Owner/Admin or an API key for the organization may edit addresses. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Request body: addresses (TransactionAddressUpdateItem[], required) - The transaction addresses to update; at most 1000 per request. id (string) - Id of the address to update, or `null` to upsert by transaction and type. transactionId (string, required) - Id of the transaction the address belongs to. type (PublicAddressTypeEnum, required) - Address role to set (`SHIP_TO` or `BILL_TO`). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM street1 (string) - First line of the street address. Omit or send `null` to clear; send a value to set. street2 (string) - Second line of the street address. Omit or send `null` to clear; send a value to set. city (string) - City or locality. Omit or send `null` to clear; send a value to set. county (string) - County or district. Omit or send `null` to clear; send a value to set. state (string) - State or province code. Omit or send `null` to clear; send a value to set. postalCode (string) - Postal or ZIP code. Omit or send `null` to clear; send a value to set. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Omit or send `null` to clear; send a value to set. fullAddress (string) - Single-line full address. Omit or send `null` to clear; send a value to set. phone (string) - Contact phone for the address. Omit or send `null` to clear; send a value to set. isUnincorporated (boolean) - When `true`, city-level tax rates are not applied to this address. Omit or send `null` to leave the stored value unchanged; send `false` to clear it. Response fields: [truncated, see the reference page] --- # Validate and enrich an address POST /addresses/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-and-enrich-an-address POST /addresses/validate Validate and enrich an address Validate an address and return the standardized, enriched version of it along with whether it verified and which fields were added or corrected. The address is validated against postal reference data; components such as `county` are filled in when they can be. Returns 400 if the country is not supported, and 503 if the address validation service is temporarily unavailable. Category: Addresses Request body: street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. fullAddress (string) - Single-line full address, as an alternative to fields. phone (string) - Contact phone for the address. Response fields: submittedAddress (PublicAddress, required) - The address exactly as it was submitted. street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code, or `null` when the source supplied none. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`, or `null` when none was supplied. fullAddress (string) - Single-line full address as the source supplied it, or `null` when it supplied none. standardizedAddress (PublicAddress, required) - The standardized and enriched version of the submitted address. street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. [truncated, see the reference page] --- # List API keys GET /api-keys Source: https://docs.trykintsugi.com/reference/2026-10-06/list-api-keys GET /api-keys List API keys List API keys. Requires a user credential (an Owner or Admin) or a PORTFOLIO-scope Api-Key. Select an organization with an `Organization-Id` to list that organization's keys (`active` toggles current vs archived); omit it to list a portfolio's keys if you are a portfolio Owner or Admin bearer. Paging is forward-only and offset-backed (the cursor encodes a page number, not a keyset bound): pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page, and `previousCursor` / `hasPrevious` are always null/false. On a portfolio listing, optional `scope` (`PORTFOLIO` or `ORGANIZATION`) splits the mixed set for dual-table UIs; omit it for every key. A cursor is only valid for the `limit`, `active`, `scope`, and organization or portfolio it was issued under; change any of those and start from the first page. Category: API Keys Query parameters: active (boolean) - For an organization's own keys, list current (`true`, the default) or archived (`false`) keys. A portfolio or client listing has no archived state, so `false` is rejected there rather than ignored. scope (PublicApiKeyScopeEnum) - On a portfolio listing (no `Organization-Id`), keep only `PORTFOLIO` keys or only `ORGANIZATION` keys (including null-scope legacy keys). Omit for the full mixed set. Rejected on an organization or client listing. allowed values: ORGANIZATION, PORTFOLIO limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (ApiKey[], required) - API keys on this page. id (string, required) - Opaque unique identifier of the API key. Treat as opaque; do not parse. scope (PublicApiKeyScopeEnum, required) - Tier the key grants. `ORGANIZATION` acts on one organization (a direct org key, or a portfolio-minted key for one client); `PORTFOLIO` is a portfolio-wide key for the partner APIs. Null for a key whose stored tier is unrecognized: it grants no access and should be revoked. allowed values: ORGANIZATION, PORTFOLIO organizationId (string, required) - Organization the key acts on for a direct org key, or null for a portfolio-minted key (see `clientOrganizationId`) or a portfolio-wide key. [truncated, see the reference page] --- # Create an API key POST /api-keys Source: https://docs.trykintsugi.com/reference/2026-10-06/create-an-api-key POST /api-keys Create an API key Create an API key and return its one-time secret token (shown only here). Requires a user credential (an Owner or Admin) or a PORTFOLIO-scope Api-Key. Select an organization with an `Organization-Id` to create an organization key (a portfolio Owner/Admin bearer, or a portfolio Api-Key, selecting a client org creates a client-scoped key); omit it to create a portfolio-wide key if you are a portfolio Owner or Admin bearer. Portfolio and client keys are capped: creating one past the cap returns 409. An organization key returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include API keys. Client-scoped and portfolio-wide keys are not plan-gated. Category: API Keys Request body: expiresAt (string) - When the key should expire (RFC-3339 UTC with an explicit Z). Must be in the future. Omit for a key that does not expire. Response fields: id (string, required) - Opaque unique identifier of the created key. Treat as opaque. token (string, required) - The secret API-key token. Shown ONCE, here, at creation; it cannot be retrieved later. Store it securely. Response statuses: 201, 400, 401, 403, 404, 409, 422, 503 --- # Update an API key PATCH /api-keys/{api_key_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-an-api-key PATCH /api-keys/{api_key_id} Update an API key Update an organization API key's expiry. Requires a user credential (an Owner or Admin of the organization, selected with an `Organization-Id`). A PORTFOLIO-scope Api-Key caller still must select a target (403 without one, matching every other verb on this family) but is always refused once it has (404), since client-scoped keys have no update capability for any caller. Only a direct organization key can be updated; any other key returns 404. Send `expiresAt` to set a new expiry or null to remove it; an empty body returns 400. The response is empty on success. Category: API Keys Path parameters: api_key_id (string, required) - Opaque identifier of the API key to update. Treat as opaque. Request body: expiresAt (string) - New expiry for the key (RFC-3339 UTC with an explicit Z), which must be in the future. Send null to remove the expiry so the key never expires. Omit the field and the request is rejected, since there is nothing to change. Response statuses: 204, 400, 401, 403, 404, 409, 422, 503 --- # Revoke an API key DELETE /api-keys/{api_key_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/revoke-an-api-key DELETE /api-keys/{api_key_id} Revoke an API key Revoke an API key. Requires a user credential (an Owner or Admin) or a PORTFOLIO-scope Api-Key. Select an organization with an `Organization-Id` to revoke one of its keys; omit it to revoke a portfolio key if you are a portfolio Owner or Admin bearer. A PORTFOLIO Api-Key caller must always send `Organization-Id` naming a client in its own portfolio and can revoke only that client's keys; it can never revoke the portfolio's own portfolio-wide key. Returns 404 if the key is not one you can revoke; the response is empty on success. Category: API Keys Path parameters: api_key_id (string, required) - Opaque identifier of the API key to revoke. Treat as opaque. Response statuses: 204, 400, 401, 403, 404, 409, 422, 503 --- # List attachments for a related entity GET /attachments Source: https://docs.trykintsugi.com/reference/2026-10-06/list-attachments-for-a-related-entity GET /attachments List attachments for a related entity List the attachments held against one related entity, most recent first. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `relatedEntityId` and `relatedEntityType` are both required. Returns an empty list when the entity has no attachments, or is not one your credential can access. Category: Attachments Query parameters: relatedEntityId (string, required) - The related entity whose attachments to list. relatedEntityType (string, required) - Kind of related entity. Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Upload an attachment POST /attachments Source: https://docs.trykintsugi.com/reference/2026-10-06/upload-an-attachment POST /attachments Upload an attachment Attach a document to a related entity in the resolved organization, as `multipart/form-data` with the file in the `file` part and `relatedEntityId` and `relatedEntityType` as form fields. Returns the stored attachment's metadata. Returns 404 if the related entity does not exist or belongs to an organization your credential cannot access. The file must be at most 10 MB. Category: Attachments Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422 --- # Get an attachment by id GET /attachments/{attachment_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-an-attachment-by-id GET /attachments/{attachment_id} Get an attachment by id Fetch a single attachment's metadata by id. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the attachment does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Category: Attachments Path parameters: attachment_id (string, required) - The unique identifier of the attachment. Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Download an attachment GET /attachments/{attachment_id}/download Source: https://docs.trykintsugi.com/reference/2026-10-06/download-an-attachment GET /attachments/{attachment_id}/download Download an attachment Return an attachment's metadata and a short-lived URL to download its bytes. Searched across every organization your credential owns, so no selector is needed for a known id. Fetch `downloadUrl` directly with a GET; it expires after `expiresInSeconds`. Returns 404 if the attachment does not exist or belongs to an organization your credential cannot access. Category: Attachments Path parameters: attachment_id (string, required) - The unique identifier of the attachment. Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. downloadUrl (string, required) - Time-limited URL to download the attachment bytes. Fetch it directly with a GET; do not send your API credentials to it. It stops working after `expiresInSeconds`, so request this endpoint again for a fresh URL rather than storing it. expiresInSeconds (integer, required) - Seconds from now until `downloadUrl` stops working. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Update bank details PATCH /bank-details Source: https://docs.trykintsugi.com/reference/2026-10-06/update-bank-details PATCH /bank-details Update bank details Partial update of the organization's bank details. Fields you omit keep their stored value; a field sent as null is cleared. Creates the record when none exists. The response masks the account and routing numbers to their last four characters. Admin or Owner only for a user credential; an API key is permitted. The organization is selected by Organization-Id, Connection-Id, or Entity-Id. Category: Bank Details Request body: bankName (string) - Name of the bank. Send null to clear it. accountNumber (string) - Bank account number. Send null to clear it. accountType (PublicBankAccountTypeEnum) - Account type. Send null to clear it. allowed values: CHECKING, SAVINGS accountHolderName (string) - Name on the account. Send null to clear it. routingNumber (string) - Bank routing number. Send null to clear it. Response fields: id (string, required) - Opaque identifier of the bank-details record. bankName (string, required) - Name of the bank, or null when not captured. accountNumberLast4 (string, required) - Last four characters of the account number, or null when not captured. accountType (PublicBankAccountTypeEnum, required) - Account type, or null when not captured. allowed values: CHECKING, SAVINGS accountHolderName (string, required) - Name on the account, or null when not captured. routingNumberLast4 (string, required) - Last four characters of the routing number, or null when not captured. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get the organization's chargebee subscription GET /billing Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-organization-s-chargebee-subscription GET /billing Get the organization's chargebee subscription Returns the plan, subscription, customer, and payment method for the org selected by Organization-Id, Connection-Id, or Entity-Id. subscription, customer, and card are null when the org never checked out or Chargebee is degraded; hasBillingAccount and hasDefaultPaymentMethod tell the cases apart. Category: Billing Response fields: billingPlan (PublicBillingPlanEnum, required) - The organization's plan. allowed values: FREE, GROWTH, PREMIUM subscriptionId (string) - Chargebee subscription id, or null if unset. subscription (Subscription) - The Chargebee subscription, or null if unset. id (string, required) - Chargebee subscription id. status (PublicSubscriptionStatusEnum, required) - Subscription status. allowed values: FUTURE, IN_TRIAL, ACTIVE, NON_RENEWING, PAUSED, CANCELLED, TRANSFERRED currency (PublicCurrencyEnum, required) - ISO-4217 currency for all amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) billingPeriod (integer, required) - Length of one billing cycle. billingPeriodUnit (string, required) - Unit for `billingPeriod`, e.g. `month` or `year`. currentTermStart (string) - Start of the current billing term. currentTermEnd (string) - End of the current billing term. nextBillingAt (string) - When the next invoice is expected. coupon (string) - Coupon code applied to the subscription, if any. items (SubscriptionItem[], required) - Priced lines on the subscription. itemPriceId (string, required) - Chargebee item price id for this line. itemType (string, required) - Kind of line, e.g. `plan`, `addon`, or `charge`. quantity (integer) - Quantity, when metered. unitPrice (string, required) - Price per unit, in the subscription's currency. amount (string) - Total amount for this line, when set. customer (BillingCustomer) - The Chargebee customer, or null if unset. email (string, required) - Billing contact email address. billingAddress (BillingAddress) - Billing contact address, or null if not captured. firstName (string) - Contact first name. lastName (string) - Contact last name. line1 (string) - Street address line 1. line2 (string) - Street address line 2. city (string) - City. state (string) - State or province name. [truncated, see the reference page] --- # Update the organization's billing contact email PATCH /billing Source: https://docs.trykintsugi.com/reference/2026-10-06/update-the-organization-s-billing-contact-email PATCH /billing Update the organization's billing contact email Updates the Chargebee billing contact email for the org selected by Organization-Id, Connection-Id, or Entity-Id. Requires a Chargebee customer to already exist (set on first checkout or portal session). Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Request body: email (string, required) - New billing contact email address. Response fields: email (string, required) - Billing contact email address. billingAddress (BillingAddress) - Billing contact address, or null if not captured. firstName (string) - Contact first name. lastName (string) - Contact last name. line1 (string) - Street address line 1. line2 (string) - Street address line 2. city (string) - City. state (string) - State or province name. stateCode (string) - State or province code. country (string) - ISO country code or name as stored by Chargebee. zip (string) - Postal code. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get the organization's billing history chart GET /billing/analytics Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-organization-s-billing-history-chart GET /billing/analytics Get the organization's billing history chart Returns up to 12 months of invoiced and pending amounts for the org selected by Organization-Id, Connection-Id, or Entity-Id. Empty when the organization has no Chargebee subscription. Category: Billing Response fields: months (BillingChartMonth[], required) - One entry per month. label (string, required) - Three-letter month abbreviation, e.g. `Oct`. month (integer, required) - Month number (1-12). year (integer, required) - Calendar year. amount (string, required) - Total amount for the month. currency (PublicCurrencyEnum, required) - ISO-4217 currency of `amount`. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) status (PublicBillingChartStatusEnum, required) - Whether the month is invoiced, still pending, or has no activity. allowed values: invoiced, pending, no_actions Response statuses: 200, 400, 401, 404, 422 --- # Start a hosted chargebee checkout POST /billing/checkout Source: https://docs.trykintsugi.com/reference/2026-10-06/start-a-hosted-chargebee-checkout POST /billing/checkout Start a hosted chargebee checkout Creates a one-time hosted checkout URL for the org selected by Organization-Id, Connection-Id, or Entity-Id to subscribe to the given plan. `PREMIUM` checks out at the org's preset price; `GROWTH` checks out at the standard metered price. `FREE` is not checkout-able. Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Request body: billingPlan (PublicBillingWritePlanEnum, required) - Plan tier to check out into. `FREE` is not checkout-able. allowed values: GROWTH, PREMIUM Response fields: id (string, required) - Chargebee hosted page id. url (string, required) - One-time hosted checkout URL. Treat as a secret. state (string, required) - Hosted page lifecycle state, e.g. `created`. expiresAt (string, required) - When the checkout URL expires. Response statuses: 201, 400, 401, 403, 404, 409, 422 --- # Get the organization's billing-lock detail GET /billing/details Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-organization-s-billing-lock-detail GET /billing/details Get the organization's billing-lock detail Returns the plan, subscription status, and effective entitlement for the org selected by Organization-Id, Connection-Id, or Entity-Id. This is what gates access to most of the product. Category: Billing Response fields: billingPlan (PublicBillingPlanEnum, required) - The organization's plan. allowed values: FREE, GROWTH, PREMIUM subscriptionStatus (PublicSubscriptionStatusEnum, required) - Lifecycle status of the Chargebee subscription. allowed values: FUTURE, IN_TRIAL, ACTIVE, NON_RENEWING, PAUSED, CANCELLED, TRANSFERRED effectiveEntitlement (PublicEffectiveEntitlementEnum, required) - Effective feature tier, which can read higher than `billingPlan` for a partner-associated or test organization. allowed values: FREE, PAID, PREMIUM billingPreset (PublicBillingPresetEnum) - Sales-led Premium staging while the organization is still FREE. Does not unlock Premium entitlements by itself. allowed values: NONE, PREMIUM capabilities (CapabilityAccess[], required) - Access to each capability, one entry per capability. `null` when access does not depend on per-capability settings for this organization; gate on `effectiveEntitlement` instead. capability (string, required) - The capability. New values may be added; ignore a capability you do not gate on. allowed values: USE_TAX, ECM, CUSTOM_ANALYTICS, FILING_READY_REPORTS, TAX_ENGINE, API_KEYS, KINTSUGI_MAIL, MANAGED_REGISTRATIONS, MANAGED_FILINGS access (PublicCapabilityAccessEnum, required) - Whether the organization may use the capability. allowed values: INCLUDED, NOT_INCLUDED, REQUIRES_PAID_PLAN Response statuses: 200, 400, 401, 404, 422 --- # Get the current month's billing estimate GET /billing/estimate Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-current-month-s-billing-estimate GET /billing/estimate Get the current month's billing estimate Returns the estimated charge for the current billing month for the org selected by Organization-Id, Connection-Id, or Entity-Id. Requires a paid plan, an active partner association, or a test organization. Category: Billing Response fields: filings (integer, required) - Billable filings completed so far this month. registrations (integer, required) - Billable registrations completed so far this month. unitCost (string, required) - Price per filing or registration on the Growth plan. currency (PublicCurrencyEnum, required) - ISO-4217 currency of the amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) premium (boolean, required) - Whether the organization is on the Premium plan. estimatedAmount (string, required) - Estimated charge for the current month: the flat Premium price, or unitCost times the combined filings and registrations count. Response statuses: 200, 400, 401, 403, 404, 422 --- # List the organization's invoices GET /billing/invoices Source: https://docs.trykintsugi.com/reference/2026-10-06/list-the-organization-s-invoices GET /billing/invoices List the organization's invoices Returns up to the last 12 months of Chargebee invoices for the org selected by Organization-Id, Connection-Id, or Entity-Id, newest first. Empty when the organization has no Chargebee subscription. Category: Billing Response fields: id (string, required) - Chargebee invoice id. status (string, required) - Invoice status as reported by Chargebee. currency (PublicCurrencyEnum) - ISO-4217 currency for all amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) recurring (boolean, required) - Whether this invoice is a recurring charge. date (string) - When the invoice was issued. dueDate (string) - When payment is due. paidAt (string) - When the invoice was paid, or null if unpaid. subTotal (string) - Charges before tax. tax (string) - Total tax charged. total (string) - Total invoice amount. amountPaid (string) - Amount paid so far. amountDue (string) - Amount still owed. lineItems (InvoiceLineItem[], required) - Charges on this invoice. entityId (string) - Id of the priced entity this line bills, if any. description (string, required) - Human-readable description of the charge. amount (string) - Line amount. issuedCreditNotes (CreditNote[], required) - Credit notes issued against this invoice. id (string, required) - Chargebee credit note id. total (string, required) - Total credited amount. status (string, required) - Credit note status as reported by Chargebee. Response statuses: 200, 400, 401, 404, 422 --- # Download one invoice as a PDF GET /billing/invoices/{invoice_id}/pdf Source: https://docs.trykintsugi.com/reference/2026-10-06/download-one-invoice-as-a-pdf GET /billing/invoices/{invoice_id}/pdf Download one invoice as a PDF Downloads one Chargebee invoice as a PDF file, for the org selected by Organization-Id, Connection-Id, or Entity-Id. Category: Billing Path parameters: invoice_id (string, required) Response statuses: 200, 400, 401, 404, 422, 503 --- # Get usage detail for one invoice GET /billing/invoices/{invoice_id}/usage Source: https://docs.trykintsugi.com/reference/2026-10-06/get-usage-detail-for-one-invoice GET /billing/invoices/{invoice_id}/usage Get usage detail for one invoice Returns the parsed usage lines billed on one invoice, for the org selected by Organization-Id, Connection-Id, or Entity-Id. Category: Billing Path parameters: invoice_id (string, required) Response fields: state (string) - US state or Canadian province code, if applicable. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. requestType (string) - Kind of billable action, e.g. `filing`. completionDate (string, required) - Date the billed action completed, as reported by Chargebee. Response statuses: 200, 400, 401, 404, 422 --- # Update the organization's subscription plan PATCH /billing/plan Source: https://docs.trykintsugi.com/reference/2026-10-06/update-the-organization-s-subscription-plan PATCH /billing/plan Update the organization's subscription plan Moves the existing Chargebee subscription of the org selected by Organization-Id, Connection-Id, or Entity-Id to the given plan. Requires a subscription to already exist; use POST /billing/checkout for a first-time checkout. Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Request body: billingPlan (PublicBillingWritePlanEnum, required) - Plan tier to update the existing subscription to. allowed values: GROWTH, PREMIUM Response fields: id (string, required) - Chargebee subscription id. status (PublicSubscriptionStatusEnum, required) - Subscription status. allowed values: FUTURE, IN_TRIAL, ACTIVE, NON_RENEWING, PAUSED, CANCELLED, TRANSFERRED currency (PublicCurrencyEnum, required) - ISO-4217 currency for all amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) billingPeriod (integer, required) - Length of one billing cycle. billingPeriodUnit (string, required) - Unit for `billingPeriod`, e.g. `month` or `year`. currentTermStart (string) - Start of the current billing term. currentTermEnd (string) - End of the current billing term. nextBillingAt (string) - When the next invoice is expected. coupon (string) - Coupon code applied to the subscription, if any. items (SubscriptionItem[], required) - Priced lines on the subscription. itemPriceId (string, required) - Chargebee item price id for this line. itemType (string, required) - Kind of line, e.g. `plan`, `addon`, or `charge`. quantity (integer) - Quantity, when metered. unitPrice (string, required) - Price per unit, in the subscription's currency. amount (string) - Total amount for this line, when set. Response statuses: 200, 400, 401, 403, 404, 422 --- # Create a chargebee self-serve customer portal session POST /billing/portal-session Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-chargebee-self-serve-customer-portal-session POST /billing/portal-session Create a chargebee self-serve customer portal session Creates a Chargebee self-serve customer portal session (URL, token, and the fields Chargebee.js needs) for the org selected by Organization-Id, Connection-Id, or Entity-Id. Creates the Chargebee customer record on first use, billed to the authenticated identity's name and email. Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Response fields: id (string, required) - Chargebee portal session id. token (string, required) - Portal session token. Treat as a secret. accessUrl (string, required) - One-time portal URL. Treat as a secret. status (string, required) - Portal session status, e.g. `created`. createdAt (string, required) - When the session was created. expiresAt (string, required) - When the portal URL expires. object (string, required) - Chargebee object type, `portal_session`. customerId (string, required) - Chargebee customer id the session is for. redirectUrl (string) - Where the portal sends the user on exit, or null. linkedCustomers (PortalLinkedCustomer[], required) - Other Chargebee customers reachable from this session. customerId (string, required) - Chargebee customer id. email (string, required) - Email of the linked customer. hasActiveSubscription (boolean, required) - Whether the linked customer has an active subscription. hasBillingAddress (boolean, required) - Whether the linked customer has a billing address on file. hasPaymentMethod (boolean, required) - Whether the linked customer has a payment method on file. object (string, required) - Chargebee object type, `linked_customer`. Response statuses: 201, 400, 401, 403, 404, 422 --- # Get unbilled usage since the last invoice GET /billing/unbilled-usages Source: https://docs.trykintsugi.com/reference/2026-10-06/get-unbilled-usage-since-the-last-invoice GET /billing/unbilled-usages Get unbilled usage since the last invoice Returns completed actions not yet reflected on an invoice, for a Growth-plan org selected by Organization-Id, Connection-Id, or Entity-Id. Empty for any other plan or a Growth org with no Chargebee subscription yet. Category: Billing Response fields: actions (UnbilledAction[], required) - Completed, unbilled actions. actionType (PublicUnbilledActionTypeEnum, required) - Kind of action. allowed values: Filing, Registration, Deregistration countryCode (string, required) - ISO 3166-1 alpha-2 country code where the action occurred, such as `US`, `CA` or `GB`. jurisdiction (string, required) - Jurisdiction name where the action occurred. completed (string, required) - Date the action completed. count (integer, required) - Total number of unbilled actions. unitCost (string, required) - Price per action from the current Chargebee subscription. currency (PublicCurrencyEnum, required) - ISO-4217 currency of the amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) nextBillingAt (string) - When the next invoice is expected. lastInvoice (LastInvoiceSummary) - Summary of the last invoice, or null if none exists. amount (string) - Total amount of the last invoice. paidAt (string) - When the last invoice was paid, or null if unpaid. Response statuses: 200, 400, 401, 404, 422, 503 --- # List certificate imports by review status GET /certificate-imports Source: https://docs.trykintsugi.com/reference/2026-10-06/list-certificate-imports-by-review-status GET /certificate-imports List certificate imports by review status List certificate imports filtered by review status, so a client can build a review queue. Repeat the `status` query parameter for multiple values (e.g. `?status=NEEDS_REVIEW&status=READY_TO_APPROVE`). Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Returns an empty list when nothing matches. Category: Certificate Imports Query parameters: status (string[], required) - Review status filter. Repeat for multiple values. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED customerId (string, required) - Customer that OCR matched this certificate to, or null when no customer has been matched. customerMatchStatus (PublicCustomerMatchStatusEnum, required) - Outcome of the OCR customer match, or null before matching has run. allowed values: MATCHED, SUGGESTED, UNMATCHED createdAt (string, required) - When the import was created, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When the import was last updated, as an RFC-3339 UTC timestamp; equal to createdAt for an import that has not been modified since creation. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Approve multiple certificate imports POST /certificate-imports/bulk-approve Source: https://docs.trykintsugi.com/reference/2026-10-06/approve-multiple-certificate-imports POST /certificate-imports/bulk-approve Approve multiple certificate imports Approve several certificate imports in the resolved organization in one request, each with its own approval values. This is non-atomic: each import is approved independently, so a failure on one does not roll back the others. The response carries a per-import outcome, with an `error` on any that failed. Returns 404 if the resolved organization is not one your credential can access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Request body: items (CertificateImportBulkApproveItem[], required) - The certificate imports to approve, each with its approval values. customerId (string, required) - Customer to link the created exemption(s) to. jurisdictions (string[], required) - Two-letter jurisdiction codes to create an exemption for; one exemption is created per entry. exemptionType (PublicCertificateImportExemptionTypeEnum) - Exemption type to create. allowed values: CUSTOMER, WHOLESALE, TRANSACTION, REVERSE_CHARGE startDate (string, required) - Exemption start date as `YYYY-MM-DD`. endDate (string) - Exemption end date as `YYYY-MM-DD`, or null when the exemption does not expire. fein (string) - Federal Employer Identification Number, or null if not provided. salesTaxId (string) - State sales tax ID or permit number, or null if not provided. buyerBusinessName (string) - Corrected buyer business name to persist, or null to leave it unchanged. sellerBusinessName (string) - Corrected seller business name to persist, or null to leave it unchanged. certificateImportId (string, required) - Kintsugi's unique identifier for the certificate import to approve. Response fields: total (integer, required) - Number of imports in the request. approved (integer, required) - Number of imports that were approved. failed (integer, required) - Number of imports that failed to approve. results (CertificateImportBulkApproveResultItem[], required) - Per-import outcome, in request order. certificateImportId (string, required) - The certificate import this result is for. status (PublicBulkApproveResultStatusEnum, required) - Whether this import was approved or failed. Branch on this, not the error message. allowed values: approved, failed [truncated, see the reference page] --- # Confirm a bulk certificate upload POST /certificate-imports/confirm-upload Source: https://docs.trykintsugi.com/reference/2026-10-06/confirm-a-bulk-certificate-upload POST /certificate-imports/confirm-upload Confirm a bulk certificate upload Confirm that files finished uploading to S3, so they can be processed for OCR review. Send the `uploadSessionId` from initiating the upload and the `certificateImportIds` that uploaded successfully. Returns 404 if the session does not exist or belongs to an organization your credential cannot access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Request body: uploadSessionId (string, required) - The uploadSessionId returned from initiating the upload. certificateImportIds (string[], required) - The certificateImportIds that were successfully uploaded to S3. Response fields: confirmedCount (integer, required) - Number of files confirmed and queued for OCR processing. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List certificate imports by upload session GET /certificate-imports/sessions/{upload_session_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/list-certificate-imports-by-upload-session GET /certificate-imports/sessions/{upload_session_id} List certificate imports by upload session List every certificate import in one upload session, so a client can watch OCR review progress. Searched across every organization your credential owns, so no selector is needed for a known session. Returns 404 if the session does not exist or belongs to an organization your credential cannot access. Category: Certificate Imports Path parameters: upload_session_id (string, required) - The upload session to list imports for. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED customerId (string, required) - Customer that OCR matched this certificate to, or null when no customer has been matched. customerMatchStatus (PublicCustomerMatchStatusEnum, required) - Outcome of the OCR customer match, or null before matching has run. allowed values: MATCHED, SUGGESTED, UNMATCHED createdAt (string, required) - When the import was created, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When the import was last updated, as an RFC-3339 UTC timestamp; equal to createdAt for an import that has not been modified since creation. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Initiate a bulk certificate upload POST /certificate-imports/upload-urls Source: https://docs.trykintsugi.com/reference/2026-10-06/initiate-a-bulk-certificate-upload POST /certificate-imports/upload-urls Initiate a bulk certificate upload Begin a bulk certificate upload in the resolved organization. Creates a certificate-import row per file and returns an `uploadSessionId` plus a presigned S3 upload target for each. POST each file as `multipart/form-data` to its `uploadUrl` including every `uploadFields` entry, then call the confirm endpoint with the same `uploadSessionId`. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Request body: files (CertificateImportFile[], required) - The files to upload in this batch. fileName (string, required) - Original filename including extension. The extension must be one of .jpeg, .jpg, .pdf, .png, .zip. mimeType (string, required) - Media type of the file. Response fields: uploadSessionId (string, required) - Identifier grouping every file in this upload batch. Pass it to the confirm and list-by-session endpoints. files (CertificateImportUploadTarget[], required) - One presigned upload target per requested file. certificateImportId (string, required) - Kintsugi's unique identifier for the created certificate import. fileName (string, required) - The filename this upload target is for. uploadUrl (string, required) - Short-lived S3 URL to POST the file's bytes to as `multipart/form-data`. uploadFields (CertificateUploadField[], required) - Form fields to include in the multipart POST alongside the file. key (string, required) - Form field name to send in the multipart upload. value (string, required) - Value to send for this form field. Response statuses: 201, 400, 401, 403, 404, 409, 422 --- # Approve a certificate import POST /certificate-imports/{certificate_import_id}/approve Source: https://docs.trykintsugi.com/reference/2026-10-06/approve-a-certificate-import POST /certificate-imports/{certificate_import_id}/approve Approve a certificate import Approve a reviewed certificate import in the resolved organization. Creates one exemption per entry in `jurisdictions`, links each to `customerId`, attaches the uploaded file, and moves the import to `APPROVED`. Send the final (possibly reviewer-corrected) certificate values in the body. Returns the updated import. Returns 409 if the import is not in a reviewable state (for example, already approved or rejected), and 404 if it does not exist or belongs to an organization your credential cannot access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Path parameters: certificate_import_id (string, required) - The unique identifier of the certificate import to approve. Request body: customerId (string, required) - Customer to link the created exemption(s) to. jurisdictions (string[], required) - Two-letter jurisdiction codes to create an exemption for; one exemption is created per entry. exemptionType (PublicCertificateImportExemptionTypeEnum) - Exemption type to create. allowed values: CUSTOMER, WHOLESALE, TRANSACTION, REVERSE_CHARGE startDate (string, required) - Exemption start date as `YYYY-MM-DD`. endDate (string) - Exemption end date as `YYYY-MM-DD`, or null when the exemption does not expire. fein (string) - Federal Employer Identification Number, or null if not provided. salesTaxId (string) - State sales tax ID or permit number, or null if not provided. buyerBusinessName (string) - Corrected buyer business name to persist, or null to leave it unchanged. sellerBusinessName (string) - Corrected seller business name to persist, or null to leave it unchanged. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED [truncated, see the reference page] --- # Get a certificate import's file URL GET /certificate-imports/{certificate_import_id}/file-url Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-certificate-import-s-file-url GET /certificate-imports/{certificate_import_id}/file-url Get a certificate import's file URL Return a short-lived URL to download an imported certificate's file. Searched across every organization your credential owns, so no selector is needed for a known id. Fetch `url` directly with a GET; it expires after `expiresInSeconds`. Returns 404 if the import does not exist or belongs to an organization your credential cannot access. Category: Certificate Imports Path parameters: certificate_import_id (string, required) - The unique identifier of the certificate import. Response fields: url (string, required) - Short-lived S3 URL to GET the file's bytes. expiresInSeconds (integer, required) - Lifetime of `url` in seconds; request the endpoint again for a fresh one after it expires. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Reject a certificate import POST /certificate-imports/{certificate_import_id}/reject Source: https://docs.trykintsugi.com/reference/2026-10-06/reject-a-certificate-import POST /certificate-imports/{certificate_import_id}/reject Reject a certificate import Reject a certificate import in the resolved organization, moving it to `REJECTED` and out of the review queue. Returns the updated import. Returns 409 if the import has already been approved, and 404 if it does not exist or belongs to an organization your credential cannot access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Path parameters: certificate_import_id (string, required) - The unique identifier of the certificate import to reject. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED customerId (string, required) - Customer that OCR matched this certificate to, or null when no customer has been matched. customerMatchStatus (PublicCustomerMatchStatusEnum, required) - Outcome of the OCR customer match, or null before matching has run. allowed values: MATCHED, SUGGESTED, UNMATCHED createdAt (string, required) - When the import was created, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When the import was last updated, as an RFC-3339 UTC timestamp; equal to createdAt for an import that has not been modified since creation. Response statuses: 200, 400, 401, 403, 404, 409, 422, 500 --- # List compliance document catalog GET /compliance-documents Source: https://docs.trykintsugi.com/reference/2026-10-06/list-compliance-document-catalog GET /compliance-documents List compliance document catalog Returns every catalog type for the selected organization, with upload status and any stored files. Requires a user credential (an API key is rejected) that is an Owner of the organization selected by Organization-Id, Connection-Id, or Entity-Id. Category: Compliance Documents Response fields: id (string, required) - Stable catalog type id for this compliance document slot. allowed values: acquisition_documentation, articles_of_incorporation, bank_account_certificate, bank_statement, business_license, business_registration_certificate, certificate_of_authority, certificate_of_formation, certificate_of_incorporation, customs_documents, dba_registration_document, drivers_license (and 18 more, see the reference page) label (string, required) - Human-readable label for the catalog type. cardinality (PublicComplianceDocumentCardinality, required) - Whether this type holds one file or many. One-file types are replaced with PUT on the catalog type. Many-file types add with POST on the catalog type and replace a single file with PUT on that file. Deleting a file is not available yet. allowed values: ONE, MANY status (PublicComplianceDocumentStatus, required) - Whether any file is stored for this catalog type. allowed values: UPLOADED, NOT_UPLOADED lastUpdated (string, required) - Most recent create or replace among this type's files, or `null` when none are uploaded. documents (ComplianceDocumentFile[], required) - Files currently stored for this catalog type. id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Replace one file under a many-file compliance document type PUT /compliance-documents/files/{document_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/replace-one-file-under-a-many-file-compliance-document-type PUT /compliance-documents/files/{document_id} Replace one file under a many-file compliance document type Replace the bytes of one stored file under a many-file catalog type, as `multipart/form-data` with the file in the `file` part. Returns 400 when the file belongs to a one-file catalog type. The file must be a PDF, JPG, or PNG of at most 10 MB. Requires an Owner user credential. Category: Compliance Documents Path parameters: document_id (string, required) - The unique identifier of the stored file. Response fields: id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 200, 400, 401, 403, 404, 409, 413, 422, 500, 503 --- # Preview a compliance document file GET /compliance-documents/files/{document_id}/preview Source: https://docs.trykintsugi.com/reference/2026-10-06/preview-a-compliance-document-file GET /compliance-documents/files/{document_id}/preview Preview a compliance document file Return a stored file's bytes for display in a viewer. The response is the file itself, not JSON: `Content-Type` is the stored file's type and `Content-Disposition` is `inline`, so a browser renders it rather than saving it. Returns 404 if the file does not exist or belongs to an organization your credential cannot access. Requires an Owner user credential. Category: Compliance Documents Path parameters: document_id (string, required) - The unique identifier of the stored file. Response statuses: 200, 400, 401, 403, 404, 409, 422, 503 --- # Add a file to a many-file compliance document type POST /compliance-documents/{catalog_type} Source: https://docs.trykintsugi.com/reference/2026-10-06/add-a-file-to-a-many-file-compliance-document-type POST /compliance-documents/{catalog_type} Add a file to a many-file compliance document type Add a file under a many-file catalog type, as `multipart/form-data` with the file in the `file` part. Returns 400 when the catalog type holds only one file. The file must be a PDF, JPG, or PNG of at most 10 MB. Requires an Owner user credential. Category: Compliance Documents Path parameters: catalog_type (string, required) - Catalog type id. allowed values: acquisition_documentation, articles_of_incorporation, bank_account_certificate, bank_statement, business_license, business_registration_certificate, certificate_of_authority, certificate_of_formation, certificate_of_incorporation, customs_documents, dba_registration_document, drivers_license (and 18 more, see the reference page) Response fields: id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422, 500, 503 --- # Add or replace a one-file compliance document PUT /compliance-documents/{catalog_type} Source: https://docs.trykintsugi.com/reference/2026-10-06/add-or-replace-a-one-file-compliance-document PUT /compliance-documents/{catalog_type} Add or replace a one-file compliance document Put the single file for a one-file catalog type, as `multipart/form-data` with the file in the `file` part. Creates the slot on first upload and replaces the stored file after that. A replace deletes the previous file and returns a new `id`; do not reuse the old id for preview. Returns 400 when the catalog type holds many files. The file must be a PDF, JPG, or PNG of at most 10 MB. Requires an Owner user credential. Category: Compliance Documents Path parameters: catalog_type (string, required) - Catalog type id. allowed values: acquisition_documentation, articles_of_incorporation, bank_account_certificate, bank_statement, business_license, business_registration_certificate, certificate_of_authority, certificate_of_formation, certificate_of_incorporation, customs_documents, dba_registration_document, drivers_license (and 18 more, see the reference page) Response fields: id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 200, 400, 401, 403, 404, 409, 413, 422, 500, 503 --- # List connections GET /connections Source: https://docs.trykintsugi.com/reference/2026-10-06/list-connections GET /connections List connections List connections across every organization your credential can access (portfolio-wide), keyset-paginated. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Each connection maps a platform entity (`platformEntityId`) to an organization (`organizationId`), so an integration can discover which entity belongs to which org. Optionally narrow with `status` / `source` and order with `sort` / `order`; a cursor is only valid for the sort, the filters, AND the organization scope it was issued under -- change any of them and start again from the first page. Category: Connections Query parameters: status (string) - Comma-separated connection statuses (ACTIVE, INACTIVE, CONNECTION_ERROR); matches any of them. Unknown tokens are rejected with 400. source (string) - Comma-separated integration sources; matches any of them. Unknown tokens are rejected with 400. sort (PublicConnectionSortEnum) - Field to sort by. Omit for the default order: `ACTIVE` connections first, then `INACTIVE`, then `CONNECTION_ERROR`, each with the most recently updated first (`order` applies only when `sort` is set). Every offered key sorts the whole matching set, so expect a slower first page on a large portfolio. allowed values: createdAt, updatedAt, lastSynced, storeName, status, source, recordsSynced order (PublicConnectionSortOrder) - Sort direction when `sort` is set. Defaults to `desc`. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Connection[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. [truncated, see the reference page] --- # Start an acumatica oauth connect POST /connections/acumatica/oauth/authorize Source: https://docs.trykintsugi.com/reference/2026-10-06/start-an-acumatica-oauth-connect POST /connections/acumatica/oauth/authorize Start an acumatica oauth connect Return the Acumatica consent URL for the resolved organization's self-hosted instance. `clientId`/`clientSecret` are the OAuth app registered on that instance; never echoed back. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Request body: instanceUrl (string, required) - Acumatica instance base URL. clientId (string, required) - Acumatica OAuth client id. clientSecret (string, required) - Acumatica OAuth client secret. endpointVersion (string) - Acumatica contract endpoint version. endpointName (string) - Acumatica contract endpoint name. branchId (string) - Optional branch scope applied after OAuth. Response fields: authUrl (string, required) - Consent URL to redirect the user to. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Start an airwallex oauth connect POST /connections/airwallex/oauth/authorize Source: https://docs.trykintsugi.com/reference/2026-10-06/start-an-airwallex-oauth-connect POST /connections/airwallex/oauth/authorize Start an airwallex oauth connect Return the Airwallex consent URL for the resolved organization. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Response fields: authUrl (string, required) - Airwallex consent URL. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Delete an unfinished apideck connection DELETE /connections/apideck/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/delete-an-unfinished-apideck-connection DELETE /connections/apideck/{conn_id} Delete an unfinished apideck connection Remove a connection left over from a Vault flow that was cancelled or failed before activation. Only an `inactive` or `connection_error` Apideck connection that holds no data is removed, permanently: no archived row, note or audit entry is kept. Returns 409 if the connection is active (for example the activate call succeeded but its response was lost) or already holds data; nothing is changed, so it is safe to call again after a failed or uncertain activate. Returns 404 if the connection does not exist, is not an Apideck-backed connection, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. To disconnect a working connection, use `DELETE /connections/{connId}`. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Activate an apideck-backed connection POST /connections/apideck/{conn_id}/activate Source: https://docs.trykintsugi.com/reference/2026-10-06/activate-an-apideck-backed-connection POST /connections/apideck/{conn_id}/activate Activate an apideck-backed connection Activate an Apideck-backed connection after the Vault widget flow completes, with duplicate-connection handling by `shopId` (e.g. the QuickBooks realmId or the WooCommerce shop domain). Omit `shopId` to have the platform verify the Vault connection and resolve it automatically. If another connection already exists for the same `shopId`, that one is reactivated and this one is superseded. Returns 400 if the connection is not an Apideck-backed connection. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Apideck Vault call itself fails; retrying may succeed. Returns 400 with code `already_connected` when `shopId` matched a connection you already have: that connection was reactivated (and given any NetSuite or DualEntry values sent here), this one was deleted, and nothing further is needed. Send `netsuiteAccountId`, `netsuiteSubsidiaryId` or `dualentryCompanyId` here, not in a settings update beforehand, so they land on the connection that stays. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: shopId (string) - Store/company identifier for duplicate-connection checking (e.g. the QuickBooks realmId or the WooCommerce shop domain). Omit to have the platform verify the Vault connection and resolve it automatically. netsuiteAccountId (string) - NetSuite only: the account id from Vault. Written to the connection this activate keeps, which is the existing connection when `shopId` matches one. Omit to leave the stored value unchanged. Ignored for other sources. netsuiteSubsidiaryId (string) - NetSuite only: the subsidiary id from Vault. Written like `netsuiteAccountId`. Omit to leave the stored value unchanged. Ignored for other sources. dualentryCompanyId (string) - DualEntry only: the company id from Vault. Written like `netsuiteAccountId`. Omit to leave the stored value unchanged; send `null` or an empty string to scope the connection to every company. Ignored for other sources. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. [truncated, see the reference page] --- # Open an apideck vault session to edit a connection GET /connections/apideck/{conn_id}/session Source: https://docs.trykintsugi.com/reference/2026-10-06/open-an-apideck-vault-session-to-edit-a-connection GET /connections/apideck/{conn_id}/session Open an apideck vault session to edit a connection Open an Apideck Vault session for an existing connection, to re-open the widget for re-authentication or editing stored credentials. Returns 404 if the connection does not exist, is not an Apideck-backed connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 400 if Apideck rejects the Vault session request. Returns 503 if the Vault session call itself fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: sessionToken (string, required) - Apideck Vault session token to edit credentials. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Connect an apideck-backed service POST /connections/apideck/{service_id}/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-an-apideck-backed-service POST /connections/apideck/{service_id}/connect Connect an apideck-backed service Open an Apideck Vault session to connect one of the Apideck-backed services (BigCommerce, QuickBooks, Deel, Rippling, Gusto, WooCommerce, Amazon Seller Central, Etsy, Walmart, Magento, Shopware, Xero, NetSuite, Sage Intacct, Wix, Microsoft Dynamics 365 Business Central, DualEntry, Intuit Enterprise Suite). The returned `token` opens the Vault widget; complete the OAuth/credential flow there, then call the activate route with the resulting `connectionId`. `shopId`/`shopUrl` apply only to Shopware. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Vault session call fails; retrying may succeed. Category: Connections Path parameters: service_id (ApiDeckServiceEnum, required) - The Apideck service to connect. allowed values: bigcommerce, quickbooks, deel, rippling, gusto, woocommerce, amazon-seller-central, etsy, walmart, magento, shopware, xero (and 6 more, see the reference page) Request body: defaultCountry (CountryCodeEnum) - Default country for transactions imported through this connection. allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) shopId (string) - Shopware only: the shop's Apideck shop id. shopUrl (string) - Shopware only: the shop's storefront URL. Response fields: connectionId (string, required) - The new connection's id, INACTIVE until Vault activation completes. token (string, required) - Apideck Vault session token to open the connect widget. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Connect a bill.com account POST /connections/bill-com/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-bill-com-account POST /connections/bill-com/connect Connect a bill.com account Create or update a Bill.com connection (single organization per connection). Re-submitting the same `billComOrganizationId` updates its stored credentials rather than creating a second connection. Returns 409 if that Bill.com organization is already ACTIVE on a different Kintsugi organization; deactivate it there first. Returns 503 if Bill.com sync-token auth is not configured. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: syncTokenName (string, required) - Bill.com sync-token name (username). syncTokenValue (string, required) - Bill.com sync-token value (password). billComOrganizationId (string, required) - Bill.com organization id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate bill.com credentials POST /connections/bill-com/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-bill-com-credentials POST /connections/bill-com/validate Validate bill.com credentials Probe Bill.com sync-token credentials without persisting a connection, returning the entity available under them. Returns 400 if authentication fails. Returns 409 if that Bill.com organization is already ACTIVE on a different Kintsugi organization. Returns 503 if Bill.com sync-token auth is not configured. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: syncTokenName (string, required) - Bill.com sync-token name (username). syncTokenValue (string, required) - Bill.com sync-token value (password). billComOrganizationId (string, required) - Bill.com organization id. Response fields: entities (BillComValidateEntity[]) - Entities available under the validated credentials. id (string, required) - Bill.com entity id. name (string, required) - Bill.com entity display name. currency (string) - Entity base currency. Response statuses: 200, 400, 401, 403, 404, 409, 422, 503 --- # Enable tax collection on a bill.com connection POST /connections/bill-com/{conn_id}/enable-tax Source: https://docs.trykintsugi.com/reference/2026-10-06/enable-tax-collection-on-a-bill-com-connection POST /connections/bill-com/{conn_id}/enable-tax Enable tax collection on a bill.com connection Provision the Bill.com invoice webhook subscription (if needed) and enable tax calculation (L2) on a Bill.com connection. Unlike the generic enable-tax-collection action, this is required before a Bill.com connection can enable tax collection at all. A no-op that returns the connection's settings unchanged if it is already enabled and configured. Returns 400 if the connection is not ready for tax calculation. Returns 404 if the connection does not exist, is not a Bill.com connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if provisioning the webhook subscription fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. taxCollectionEnabled (boolean, required) - Whether tax calculation is enabled on this connection. defaultCountry (string) - Default tax country for this connection (ISO 3166-1 alpha-2); `null` when unset. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types this connection syncs. `null` for every non-NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor for this Airwallex connection, as YYYY-MM-DD. `null` for every non-Airwallex connection, or when unset. woocommerceHistoricalSyncStartDate (string) - Import floor for this WooCommerce connection, as YYYY-MM-DD. `null` for every non-WooCommerce connection, or when unset. netsuiteHistoricalSyncStartDate (string) - Import floor for this NetSuite connection, as YYYY-MM-DD. `null` for every non-NetSuite connection, or when unset. microsoftD365HistoricalSyncStartDate (string) - Import floor for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. `null` for every non-D365 connection, or when unset. amazonHistoricalSyncStartDate (string) - Import floor for this Amazon connection, as YYYY-MM-DD. `null` for every non-Amazon connection, or when unset. [truncated, see the reference page] --- # Connect a bunny account POST /connections/bunny/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-bunny-account POST /connections/bunny/connect Connect a bunny account Create a Bunny connection with a client id/secret. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Bunny API call itself fails; retrying may succeed. Category: Connections Request body: subdomain (string, required) - Bunny subdomain, e.g. `mycompany` for mycompany.bunny.com. clientId (string, required) - Bunny API client id. clientSecret (string, required) - Bunny API client secret. name (string) - Custom display name for this connection. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default 7-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Refresh a bunny connection's access token PATCH /connections/bunny/{conn_id}/refresh Source: https://docs.trykintsugi.com/reference/2026-10-06/refresh-a-bunny-connection-s-access-token PATCH /connections/bunny/{conn_id}/refresh Refresh a bunny connection's access token Re-issue a Bunny access token from new (or rotated) client credentials. Returns 400 if the credentials are invalid. Returns 404 if the connection does not exist, is not a Bunny connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Bunny API call itself fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: subdomain (string, required) - Bunny subdomain, e.g. `mycompany` for mycompany.bunny.com. clientId (string, required) - Bunny API client id. clientSecret (string, required) - Bunny API client secret. name (string) - Custom display name for this connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Connect a campfire account POST /connections/campfire/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-campfire-account POST /connections/campfire/connect Connect a campfire account Create or update Campfire connections, one per `entityIds` entry. Re-submitting an entity id updates its stored credentials rather than creating a second connection. Returns 400 if the key is invalid or an entity id is not accessible with it. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Campfire API key (Token auth). entityIds (string[], required) - One or many Campfire entity ids; one connection per id. entityNames (string[]) - Display names aligned positionally with `entityIds`. webhookSigningSecret (string) - L2 webhook signing secret shown on Campfire's webhook detail page. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. [truncated, see the reference page] --- # Validate campfire credentials POST /connections/campfire/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-campfire-credentials POST /connections/campfire/validate Validate campfire credentials Probe Campfire `GET /coa/api/entity` with the supplied API key, returning the entities it can access. Returns 400 if the key is invalid or has no accessible entities. Returns 503 if Campfire cannot be reached. Category: Connections Request body: apiKey (string, required) - Campfire API key to probe. Response fields: entities (CampfireValidateEntity[]) - Entities available under the validated key. id (string, required) - Campfire entity id. name (string, required) - Campfire entity display name. currency (string) - Entity base currency. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Update a campfire connection's webhook signing secret PATCH /connections/campfire/{conn_id}/webhook-secret Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-campfire-connection-s-webhook-signing-secret PATCH /connections/campfire/{conn_id}/webhook-secret Update a campfire connection's webhook signing secret Update only the L2 webhook signing secret on an existing Campfire connection. No API-key reprobe; an empty string clears it (back to L1-only). Returns 404 if the connection does not exist, is not a Campfire connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: webhookSigningSecret (string, required) - L2 webhook signing secret shown on Campfire's webhook detail page. An empty string clears it (reverts to L1-only). Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a chargebee account POST /connections/chargebee/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-chargebee-account POST /connections/chargebee/connect Connect a chargebee account Create or update a Chargebee connection for a site, or (with `multipleBusinessEntityEnabled`) one business entity under that site. Re-submitting for the same site (or the same site + business entity) updates the stored key rather than creating a second connection. Returns 400 if the credentials or business entity id are invalid, or if `multipleBusinessEntityEnabled` is true without a `businessEntityId`. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: siteId (string, required) - Chargebee site id. url (string, required) - Chargebee site URL. apiKey (string, required) - Chargebee API key. businessEntityId (string) - Business entity id; required when `multipleBusinessEntityEnabled`. businessEntityName (string) - Business entity display name. multipleBusinessEntityEnabled (boolean) - Connect one business entity rather than the whole site. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR [truncated, see the reference page] --- # Connect a checkoutchamp account POST /connections/checkoutchamp/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-checkoutchamp-account POST /connections/checkoutchamp/connect Connect a checkoutchamp account Create or update a CheckoutChamp connection. Re-submitting the same `loginId` and `campaignId` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. No separate validate route exists for CheckoutChamp. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: loginId (string, required) - CheckoutChamp API login id. password (string, required) - CheckoutChamp API password. campaignId (string) - Optional campaign/store id to filter orders. timezone (string) - IANA timezone for the account's reporting timezone; defaults to America/New_York. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. [truncated, see the reference page] --- # Summarize collected-tax tracking across your connections GET /connections/collecting-summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-collected-tax-tracking-across-your-connections GET /connections/collecting-summary Summarize collected-tax tracking across your connections Per-connection collected-tax tracking counts across every organization your credential can access, or one organization when you send `Organization-Id`. `pendingCount` is registrations not yet confirmed either way; `fixIssuesCount` is registrations confirmed as collecting that were later found not collecting on a transaction. A connection with no tracked registrations is omitted rather than reported with zero counts. Category: Connections Response fields: connectionId (string, required) - Connection id these counts apply to. fixIssuesCount (integer, required) - Registrations confirmed as collecting but later found not collecting on a transaction; needs attention. pendingCount (integer, required) - Registrations not yet confirmed as collecting or not. totalCount (integer, required) - All tracked registrations for this connection, confirmed or not. Response statuses: 200, 400, 401, 403, 404, 422 --- # Start an ebay oauth connect POST /connections/ebay/oauth/authorize-request Source: https://docs.trykintsugi.com/reference/2026-10-06/start-an-ebay-oauth-connect POST /connections/ebay/oauth/authorize-request Start an ebay oauth connect Return the eBay connect URL plus the `state` handle for this attempt. Returns 400 if the platform eBay app is not configured for this environment. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Returns 409 if this browser already has another organization's eBay connect in progress. Category: Connections Request body: historicalSyncStartDate (string) - Import floor chosen before consent, as YYYY-MM-DD. `null` imports all available history. Response fields: authUrl (string, required) - eBay consent URL. state (string, required) - CSRF handle identifying this attempt. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get ebay runame portal urls GET /connections/ebay/oauth/setup Source: https://docs.trykintsugi.com/reference/2026-10-06/get-ebay-runame-portal-urls GET /connections/ebay/oauth/setup Get ebay runame portal urls Return the RuName portal URLs (Auth accepted, Auth declined, privacy policy) for the current Kintsugi environment, to enter into eBay's RuName configuration before connecting. Category: Connections Response fields: authAcceptedUrl (string, required) - eBay Auth Accepted redirect URL. authDeclinedUrl (string, required) - eBay Auth Declined redirect URL. privacyPolicyUrl (string, required) - Privacy policy URL shown to eBay. Response statuses: 200, 400, 401, 403, 404, 422 --- # Start a freshbooks oauth connect POST /connections/freshbooks/oauth/authorize-request Source: https://docs.trykintsugi.com/reference/2026-10-06/start-a-freshbooks-oauth-connect POST /connections/freshbooks/oauth/authorize-request Start a freshbooks oauth connect Return the FreshBooks consent URL for the resolved organization. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Request body: historicalSyncStartDate (string) - Import floor captured at connect time, as YYYY-MM-DD. `null` imports all available history. Response fields: authUrl (string, required) - Consent URL to redirect the user to. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List freshbooks businesses awaiting selection GET /connections/freshbooks/oauth/businesses Source: https://docs.trykintsugi.com/reference/2026-10-06/list-freshbooks-businesses-awaiting-selection GET /connections/freshbooks/oauth/businesses List freshbooks businesses awaiting selection List the businesses under a pending authorization (`selectionKey`, from the OAuth callback) to choose from. Returns 400 if the selection expired or is not this organization's. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Query parameters: selectionKey (string, required) - The selection key returned by the OAuth callback. Response fields: businesses (FreshbooksOAuthBusiness[]) - Businesses available under the pending authorization. accountId (string, required) - FreshBooks account id. businessId (integer) - FreshBooks business id. name (string) - Business display name. identityId (string) - Owning FreshBooks identity id. Response statuses: 200, 400, 401, 403, 404, 422 --- # Finish connecting a freshbooks business POST /connections/freshbooks/oauth/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/finish-connecting-a-freshbooks-business POST /connections/freshbooks/oauth/connect Finish connecting a freshbooks business Create the connection for the business chosen from the businesses list. Returns 400 if the selection has expired, is not this organization's, or `accountId` is not part of it. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: selectionKey (string, required) - Key returned by the OAuth callback. accountId (string, required) - `accountId` of the business chosen from the businesses list. Response fields: success (boolean, required) - Whether the connection was created. message (string) - Human-readable outcome. Response statuses: 200, 400, 401, 403, 404, 422 --- # Enable tax collection on a freshbooks connection POST /connections/freshbooks/{conn_id}/enable-tax Source: https://docs.trykintsugi.com/reference/2026-10-06/enable-tax-collection-on-a-freshbooks-connection POST /connections/freshbooks/{conn_id}/enable-tax Enable tax collection on a freshbooks connection Register FreshBooks Events API webhook callbacks (if needed) and enable tax calculation (L2) on a FreshBooks connection. Unlike the generic enable-tax-collection action, this is required before a FreshBooks connection can enable tax collection at all. Returns 400 if the connection is not ready for tax calculation. Returns 404 if the connection does not exist, is not a FreshBooks connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if registering the webhook callbacks fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Connect a hyperline account POST /connections/hyperline/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-hyperline-account POST /connections/hyperline/connect Connect a hyperline account Create or update a Hyperline connection for one invoicing entity. Re-submitting the same `entityId` updates its stored credentials rather than creating a second connection. Returns 400 if the key or entity is invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Hyperline API key. entityId (string, required) - Hyperline invoicing entity id to connect. companyId (string) - Hyperline company id; required only when the entity has one. entityName (string) - Display name; defaults to the entity's own name. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Validate hyperline credentials POST /connections/hyperline/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-hyperline-credentials POST /connections/hyperline/validate Validate hyperline credentials Probe a Hyperline API key without persisting a connection, returning the companies and invoicing entities available under it for the connect picker. Returns 400 if the key is invalid. Category: Connections Request body: apiKey (string, required) - Hyperline API key to probe. Response fields: entities (HyperlineValidateEntity[]) - Invoicing entities available under the validated key. id (string, required) - Hyperline entity id. name (string, required) - Hyperline entity display name. companyId (string) - Owning company id. timezone (string) - Entity timezone. companies (HyperlineValidateCompany[]) - Companies available under the validated key. id (string, required) - Hyperline company id. name (string, required) - Hyperline company display name. environment (string) - Hyperline environment the key resolved against. Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect a kill bill account POST /connections/killbill/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-kill-bill-account POST /connections/killbill/connect Connect a kill bill account Create or update a Kill Bill connection for a tenant. Re-submitting the same `apiKey` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: baseUrl (string, required) - Kill Bill server base URL. apiKey (string, required) - Kill Bill tenant API key. apiSecret (string, required) - Kill Bill tenant API secret. adminUsername (string) - Kill Bill Basic-auth admin username. adminPassword (string, required) - Kill Bill Basic-auth admin password. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate kill bill credentials POST /connections/killbill/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-kill-bill-credentials POST /connections/killbill/validate Validate kill bill credentials Probe Kill Bill tenant credentials without persisting a connection, returning the resolved tenant id. Returns 400 if authentication fails. Category: Connections Request body: baseUrl (string, required) - Kill Bill server base URL. apiKey (string, required) - Kill Bill tenant API key. apiSecret (string, required) - Kill Bill tenant API secret. adminUsername (string) - Kill Bill Basic-auth admin username. adminPassword (string, required) - Kill Bill Basic-auth admin password. Response fields: tenantId (string) - Kill Bill tenant id resolved by the probe. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update a kill bill connection's HMAC secret PATCH /connections/killbill/{conn_id}/hmac-secret Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-kill-bill-connection-s-hmac-secret PATCH /connections/killbill/{conn_id}/hmac-secret Update a kill bill connection's HMAC secret Update the shared HMAC secret Kill Bill signs inbound tax callbacks with, and push it to the Kill Bill plugin config. An empty string clears L2 verification. Returns 400 if pushing the plugin config fails. Returns 404 if the connection does not exist, is not a Kill Bill connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: hmacSecret (string, required) - HMAC secret. An empty string clears L2 verification. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a maxio account POST /connections/maxio/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-maxio-account POST /connections/maxio/connect Connect a maxio account Create or update a Maxio connection with an API key and subdomain. Re-submitting the same `subdomain` updates its stored key rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Maxio API key. subdomain (string, required) - Maxio account subdomain. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default seven-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Poll an oauth connection-creation status GET /connections/oauth-creation-status/{key} Source: https://docs.trykintsugi.com/reference/2026-10-06/poll-an-oauth-connection-creation-status GET /connections/oauth-creation-status/{key} Poll an oauth connection-creation status Poll the status of an in-progress OAuth connect flow by the opaque `key` its authorize step returned. Served once, then cleared: a repeated poll with the same key after it completes returns 404, as does an unknown or expired key. Requires a valid credential but is not scoped to any organization -- the `key` itself, generated server-side during the authorize step, is what makes this safe to poll without one. Category: Connections Path parameters: key (string, required) - The opaque key returned by the authorize step. Response fields: state (string, required) - Opaque OAuth state the connect flow was started with. message (string, required) - Human-readable status of the in-progress connection. Response statuses: 200, 401, 403, 404, 422 --- # Connect an odoo account POST /connections/odoo/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-an-odoo-account POST /connections/odoo/connect Connect an odoo account Create or update an Odoo connection for a database. Re-submitting the same `database` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: baseUrl (string, required) - Odoo server base URL. database (string, required) - Odoo database name. username (string, required) - Odoo user login. apiKey (string, required) - Odoo API key or password. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default seven-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate odoo credentials POST /connections/odoo/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-odoo-credentials POST /connections/odoo/validate Validate odoo credentials Probe Odoo credentials without persisting a connection, returning the resolved user id. Returns 400 if authentication fails. Category: Connections Request body: baseUrl (string, required) - Odoo server base URL. database (string, required) - Odoo database name. username (string, required) - Odoo user email or login. apiKey (string, required) - Odoo API key or password. Response fields: uid (integer) - Odoo user id resolved by the probe. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update an odoo connection's HMAC secret PATCH /connections/odoo/{conn_id}/hmac-secret Source: https://docs.trykintsugi.com/reference/2026-10-06/update-an-odoo-connection-s-hmac-secret PATCH /connections/odoo/{conn_id}/hmac-secret Update an odoo connection's HMAC secret Update the shared HMAC secret Odoo signs inbound tax callbacks with. An empty string clears L2 verification. Returns 404 if the connection does not exist, is not an Odoo connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: hmacSecret (string, required) - HMAC secret. An empty string clears L2 verification. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a kong konnect metering & billing organization POST /connections/openmeter/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-kong-konnect-metering-billing-organization POST /connections/openmeter/connect Connect a kong konnect metering & billing organization Create or update an OpenMeter connection for one Konnect organization. Re-submitting the same organization id replaces the token and region. Returns 400 when the token is rejected or the organization id does not match the probe. Category: Connections Request body: apiKey (string, required) - Kong Konnect personal access token. region (string, required) - Konnect region: us, eu, au, me, or in. entityId (string, required) - Konnect organization id from validate. entityName (string) - Instance label. Defaults to the Konnect organization name. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate a konnect personal access token POST /connections/openmeter/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-a-konnect-personal-access-token POST /connections/openmeter/validate Validate a konnect personal access token Probe a token against one Konnect region without saving a connection. Succeeds only when Metering & Billing returns at least one customer. Category: Connections Request body: apiKey (string, required) - Kong Konnect personal access token to probe. region (string, required) - Konnect region: us, eu, au, me, or in. Response fields: entities (OpenMeterValidateEntity[]) - The Konnect organization available under this token and region. entityId (string, required) - Konnect organization id. entityName (string, required) - Konnect organization name. Response statuses: 200, 400, 401, 403, 404, 422 --- # Read openmeter connection fields for re-auth GET /connections/openmeter/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/read-openmeter-connection-fields-for-re-auth GET /connections/openmeter/{conn_id} Read openmeter connection fields for re-auth Region and instance label for the re-auth dialog. The token is write-only and is not returned. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Connection id. storeName (string) - Instance label. region (string) - Konnect region. externalId (string, required) - Konnect organization id. url (string) - Resolved Metering & Billing base URL. status (PublicConnectionStatusEnum, required) - Connection status. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect an orb account POST /connections/orb/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-an-orb-account POST /connections/orb/connect Connect an orb account Create or update an Orb connection with an API key. `siteName` identifies the Orb account and must be unique per organization; re-submitting the same `siteName` updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or `siteName` is empty. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Orb API key. siteName (string, required) - A name identifying this Orb account; unique per organization. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect an ordway account POST /connections/ordway/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-an-ordway-account POST /connections/ordway/connect Connect an ordway account Create or update an Ordway connection for a user company. Re-submitting the same `userCompany` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: userCompany (string, required) - Ordway company identifier. userEmail (string, required) - Ordway user email. userToken (string, required) - Ordway user token. apiKey (string, required) - Ordway API key. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Generate an ordway webhook secret POST /connections/ordway/{conn_id}/webhook-secret/generate Source: https://docs.trykintsugi.com/reference/2026-10-06/generate-an-ordway-webhook-secret POST /connections/ordway/{conn_id}/webhook-secret/generate Generate an ordway webhook secret Generate (or return the existing) Ordway L2 webhook secret and full webhook URL for registration in Ordway Setup -> Webhooks. Pass `regenerate=true` to rotate an existing secret; the previous secret stops verifying once rotated. Served only from this route: the secret is never returned again on a read. Returns 403 if your credential is not permitted to enable Ordway L2 (a staff-only beta). Returns 404 if the connection does not exist, is not an Ordway connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Query parameters: regenerate (boolean) Response fields: webhookUrl (string, required) - Full webhook URL to register in Ordway. webhookSecret (string, required) - Ordway L2 webhook secret. Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect a plentyone account POST /connections/plentyone/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-plentyone-account POST /connections/plentyone/connect Connect a plentyone account Re-login and create or update a PlentyONE connection for one host PID. Re-submitting the same host updates its stored credentials rather than creating a second connection, and queues a sync. Returns 400 if the credentials or host are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: host (string, required) - PlentyONE system URL or `p{PID}`. username (string, required) - Terra Accounts username. password (string, required) - Store login password. storeName (string) - Display name; defaults to the host's own name. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. marketplaceOrders (string) - How to handle marketplace orders: skip them, or tag and import. allowed values: skip, tag Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. [truncated, see the reference page] --- # Validate plentyone credentials POST /connections/plentyone/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-plentyone-credentials POST /connections/plentyone/validate Validate plentyone credentials Probe a PlentyONE host/username/password without persisting a connection, returning the one synthetic system entity available under them. Returns 400 if authentication or the host fails to resolve. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: host (string, required) - PlentyONE system URL or `p{PID}`. username (string, required) - Terra Accounts username. password (string, required) - Store login password. Response fields: entities (PlentyOneValidateEntity[]) - Systems available under the validated credentials. id (string, required) - Synthetic PlentyONE system entity id (`p{PID}`). name (string, required) - PlentyONE system display name. Response statuses: 200, 400, 401, 403, 404, 422 --- # Disconnect a quickbooks connection POST /connections/quickbooks/disconnect Source: https://docs.trykintsugi.com/reference/2026-10-06/disconnect-a-quickbooks-connection POST /connections/quickbooks/disconnect Disconnect a quickbooks connection Archive the QuickBooks connection matching `realmId` and its transactions; products and customers are archived on a best-effort basis. Searched across every organization your credential owns; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if no active QuickBooks connection matches `realmId` in an organization your credential can reach. Returns 409 if `realmId` matches more than one connection your credential can access; narrow it with a selector. Category: Connections Request body: realmId (string, required) - QuickBooks realm id (company id) to disconnect. Response fields: productsArchived (boolean, required) - Whether the connection's products were archived. `false` means a best-effort step failed and this route should be retried. customersArchived (boolean, required) - Whether the connection's customers were archived. `false` means a best-effort step failed and this route should be retried. Response statuses: 200, 400, 401, 404, 409, 422 --- # Connect a recurly account POST /connections/recurly/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-recurly-account POST /connections/recurly/connect Connect a recurly account Create or update a Recurly connection for one business entity, or the whole site when it has none. Re-submitting the same site (and business entity, when selected) updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or `businessEntityId` is missing when required. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Recurly private API key. businessEntityId (string) - Selected business entity id; required when multiple exist. businessEntityName (string) - Selected business entity display name. businessEntityCode (string) - Selected business entity code. multipleBusinessEntityEnabled (boolean) - Whether the Recurly site supports multiple entities. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. [truncated, see the reference page] --- # Validate recurly credentials POST /connections/recurly/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-recurly-credentials POST /connections/recurly/validate Validate recurly credentials Validate a Recurly API key and list the site's business entities for the connect picker. Returns `multipleBusinessEntityEnabled=false` with no entities when the site has none. Returns 400 if the key is invalid. Category: Connections Request body: apiKey (string, required) - Recurly private API key. Response fields: siteInfo (RecurlySiteInfo, required) - The validated Recurly site. siteId (string, required) - Recurly site id. subdomain (string, required) - Recurly site subdomain. region (string, required) - Recurly region (`us` or `eu`). businessEntities (RecurlyBusinessEntity[]) - Business entities available on this site. id (string, required) - Recurly business entity id. name (string, required) - Recurly business entity display name. code (string, required) - Recurly business entity code. multipleBusinessEntityEnabled (boolean, required) - Whether this Recurly site supports multiple business entities. Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect a rillet account POST /connections/rillet/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-rillet-account POST /connections/rillet/connect Connect a rillet account Create or update a Rillet connection with an API key. Re-submitting the same Rillet subsidiary updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or Rillet's organization/subsidiary info cannot be retrieved. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Rillet API key (Bearer token). historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Update a rillet connection's webhook signing token PATCH /connections/rillet/{conn_id}/webhook-token Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-rillet-connection-s-webhook-signing-token PATCH /connections/rillet/{conn_id}/webhook-token Update a rillet connection's webhook signing token Save the Rillet webhook signing token copied from the Rillet dashboard, a prerequisite for enabling L2 tax write-back. Returns 400 if the token is empty. Returns 404 if the connection does not exist, is not a Rillet connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: webhookSigningToken (string, required) - Base64 HMAC secret copied from the Rillet webhook settings. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a shopify account manually POST /connections/shopify/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-shopify-account-manually POST /connections/shopify/connect Connect a shopify account manually Create or update a Shopify connection from a manually entered Admin API access token. Re-submitting the same `shopUrl` updates its stored token rather than creating a second connection. Returns 400 if the credentials are invalid or the store is closed. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: shopUrl (string, required) - Shopify store domain, e.g. `mystore.myshopify.com`. secret (string, required) - Shopify Admin API access token. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Complete a shopify oauth connection POST /connections/shopify/oauth/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/complete-a-shopify-oauth-connection POST /connections/shopify/oauth/connect Complete a shopify oauth connection Complete a Shopify app-installation OAuth flow: looks up the access token the OAuth callback captured for `shopUrl` and creates or updates the connection with it. Re-submitting the same `shopUrl` updates its stored token rather than creating a second connection. Returns 404 if no OAuth-issued access token is found for this shop (the install session expired, or authorize was never completed). Returns 400 if the store is closed, or if `linkState` does not match an unexpired, unused link for this shop. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: shopUrl (string, required) - Shopify store domain, e.g. `mystore.myshopify.com`. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. linkState (string, required) - The one-time link token the Kintsugi app in Shopify Admin issued when the merchant started linking this store. Valid for 10 minutes, for this `shopUrl` only, and once: a connect that then fails because the store is closed still uses it up. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR [truncated, see the reference page] --- # List organizations connected to a shopify store GET /connections/shopify/organizations Source: https://docs.trykintsugi.com/reference/2026-10-06/list-organizations-connected-to-a-shopify-store GET /connections/shopify/organizations List organizations connected to a shopify store List the organizations with an active connection to the Shopify store `shopId`. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Organizations outside your credential's access are never returned. Returns an empty list when none match. Category: Connections Query parameters: shopId (string, required) - The Shopify store id (the `mystore` in `mystore.myshopify.com`). Response fields: organizationId (string, required) - Organization with an active connection to the store. Response statuses: 200, 400, 401, 403, 404, 422 --- # Start a SHOPLINE oauth connect POST /connections/shopline/oauth/authorize Source: https://docs.trykintsugi.com/reference/2026-10-06/start-a-shopline-oauth-connect POST /connections/shopline/oauth/authorize Start a SHOPLINE oauth connect Return the per-store SHOPLINE consent URL for the resolved organization. Returns 400 if `handle` is not a valid SHOPLINE store handle. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Request body: handle (string, required) - SHOPLINE store handle. historicalSyncStartDate (string) - Import floor chosen before consent, as YYYY-MM-DD. Persisted on a brand-new connection only; ignored on re-auth. `null` imports all available history. Response fields: authUrl (string, required) - SHOPLINE consent URL. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Connect a stripe account through the stripe app POST /connections/stripe/app-connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-stripe-account-through-the-stripe-app POST /connections/stripe/app-connect Connect a stripe account through the stripe app Create a Stripe connection captured through the Stripe App's OAuth installation flow. Returns 400 if the session is missing or expired. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: accountId (string, required) - Stripe account id captured by the Stripe App installation. mode (PublicStripeAppModeEnum, required) - Stripe environment the app was installed against. allowed values: TEST, LIVE, SANDBOX Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Connect a stripe account POST /connections/stripe/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-stripe-account POST /connections/stripe/connect Connect a stripe account Create or update a Stripe connection with a secret API key. Re-submitting for the same Stripe account updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or Stripe authentication fails. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: publishableKey (string, required) - Stripe publishable key. apiKey (string, required) - Stripe secret key. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Connect a vertex o-series account POST /connections/vertex-o-series/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-vertex-o-series-account POST /connections/vertex-o-series/connect Connect a vertex o-series account Create or update a Vertex O-Series connection for a partition, using either Basic Auth (`username`/`password`) or O Series Cloud OAuth (`clientId`/`clientSecret` + `partitionUuid`). Re-submitting the same `trustedId` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid, or the auth fields do not form one complete auth mode. No separate validate route exists for Vertex O-Series. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: trustedId (string, required) - Vertex Trusted ID for the partition. username (string) - Integration username (Basic Auth). password (string) - Integration password (Basic Auth). clientId (string) - O Series Cloud OAuth client id. clientSecret (string) - O Series Cloud OAuth client secret. partitionUuid (string) - O Series Cloud partition UUID; required for OAuth connect. reportingClientId (string) - Solution Reporting API client id. reportingClientSecret (string) - Solution Reporting API client secret. backfillStartDate (string) - Optional ISO date (YYYY-MM-DD) for historical backfill. reportDefinitionId (string) - Optional Transaction Detail Extract report definition UUID. soapInstanceUrl (string) - Client Utilities base for Tax Journal sync (SOAP). restInstanceUrl (string) - REST base for health checks (vertex-ws). instanceUrl (string) - Legacy single URL; inferred as SOAP or REST from its shape. name (string) - Display name; defaults to the trusted id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). [truncated, see the reference page] --- # Get a vertex o-series connection's install credentials GET /connections/vertex-o-series/{conn_id}/credentials Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-vertex-o-series-connection-s-install-credentials GET /connections/vertex-o-series/{conn_id}/credentials Get a vertex o-series connection's install credentials Return the Vertex credentials to enter into the external system's Vertex connector (Shopify / NetSuite / Zuora) to complete installation. Allocates a partition from the shared pool on the first call for this connection. Works for a connection of any source that uses Vertex as its tax engine, not only a Vertex O-Series connector connection. Served only from this route; never returned on the generic connection read. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Returns 503 if no partition is currently available. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: customerClientId (string, required) - Vertex customer client id. customerClientSecret (string, required) - Vertex customer client secret. owningPartyCode (string, required) - Vertex Company Code, always `{organizationId}-{connId}`. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Mark a vertex o-series connection as installed POST /connections/vertex-o-series/{conn_id}/mark-installed Source: https://docs.trykintsugi.com/reference/2026-10-06/mark-a-vertex-o-series-connection-as-installed POST /connections/vertex-o-series/{conn_id}/mark-installed Mark a vertex o-series connection as installed Enable Vertex tax calculation on a connection once its external system's Vertex connector is installed, and sync existing registrations. `installationWarnings` lists non-blocking setup issues found along the way. Works for a connection of any source that uses Vertex as its tax engine, not only a Vertex O-Series connector connection. Returns 400 if a NetSuite connection cannot scaffold tax types (tax calculation is disabled again in that case). Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Connect a zenskar account POST /connections/zenskar/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-zenskar-account POST /connections/zenskar/connect Connect a zenskar account Create or update a Zenskar connection. Re-submitting the same `zenskarOrgId` and `apiKey` updates the existing connection rather than creating a second one; a changed `apiKey` creates a new connection (Zenskar's own identity key). Returns 400 if the credentials are invalid. No separate validate route exists for Zenskar. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: zenskarOrgId (string, required) - Zenskar organization id. apiKey (string, required) - Zenskar API key. name (string) - Display name; defaults to the Zenskar org id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a zuora account POST /connections/zuora/connect Source: https://docs.trykintsugi.com/reference/2026-10-06/connect-a-zuora-account POST /connections/zuora/connect Connect a zuora account Create or update a Zuora connection with OAuth client credentials. Multi-Entity tenants select an `entityId` from `POST /connections/zuora/validate` first; single-entity tenants omit it. Re-submitting the same client id (and entity, for Multi-Entity) updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: clientId (string, required) - Zuora OAuth client id. clientSecret (string, required) - Zuora OAuth client secret. baseUrl (string) - Zuora API base URL; defaults to the US production URL. entityId (string) - Zuora entity id (Multi-Entity tenants only). entityName (string) - Zuora entity display name (Multi-Entity tenants only). multiEntityEnabled (boolean) - Whether this tenant is Multi-Entity. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default seven-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR [truncated, see the reference page] --- # Validate zuora credentials POST /connections/zuora/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-zuora-credentials POST /connections/zuora/validate Validate zuora credentials Validate Zuora OAuth client credentials and list the tenant's entities for the connect dropdown. Single-entity tenants return `multiEntityEnabled=false` with no entities. Returns 400 if the credentials are invalid. Category: Connections Request body: clientId (string, required) - Zuora OAuth client id. clientSecret (string, required) - Zuora OAuth client secret. baseUrl (string) - Zuora API base URL; defaults to the US production URL. Response fields: multiEntityEnabled (boolean, required) - Whether this Zuora tenant is Multi-Entity. entities (ZuoraEntity[]) - Entities available for a Multi-Entity tenant. id (string, required) - Zuora entity id. name (string, required) - Zuora entity name. displayName (string) - Entity display name. status (string) - Entity status. Response statuses: 200, 400, 401, 403, 404, 422 --- # Save zuora L2 tax setup PATCH /connections/zuora/{conn_id}/tax-setup Source: https://docs.trykintsugi.com/reference/2026-10-06/save-zuora-l2-tax-setup PATCH /connections/zuora/{conn_id}/tax-setup Save zuora L2 tax setup Persist the tenant id and Vertex Connect tax-engine ids on a Zuora connection and register webhook notifications. Enable tax collection with the settings routes afterwards. Returns 400 if `tenantId` or `zuoraVertexTaxEngineId` is empty. Returns 404 if the connection does not exist, is not a Zuora connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: tenantId (string, required) - Zuora tenant id. zuoraVertexTaxEngineId (string, required) - Vertex Connect tax engine id. zuoraVertexTaxCompanyId (string) - Vertex Connect tax company id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Get a connection by id GET /connections/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-connection-by-id GET /connections/{conn_id} Get a connection by id Fetch a single connection by id. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A connection you cannot access and one that does not exist return the same 404, so the API never confirms an id exists. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Delete a connection DELETE /connections/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/delete-a-connection DELETE /connections/{conn_id} Delete a connection Archive a connection: it stops appearing on every read immediately, and its transactions, products, and customers are archived on a best-effort basis (a partial failure is logged, not surfaced to you). Returns 404 if the connection does not exist, belongs to an organization your credential cannot access, or was already deleted; a second delete is not an idempotent no-op, so repeating it cannot be used to discover that the connection ever existed. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if tearing down the connection's webhook subscription fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response statuses: 204, 400, 401, 403, 404, 422, 503 --- # Activate a connection POST /connections/{conn_id}/activate Source: https://docs.trykintsugi.com/reference/2026-10-06/activate-a-connection POST /connections/{conn_id}/activate Activate a connection Set a connection's status to ACTIVE. A no-op that returns the connection unchanged if it is already ACTIVE. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. Returns 409 if the connection is a Bill.com connection whose external id is already ACTIVE on a different organization. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Record a connection's native-tax-disabled attestation POST /connections/{conn_id}/attest Source: https://docs.trykintsugi.com/reference/2026-10-06/record-a-connection-s-native-tax-disabled-attestation POST /connections/{conn_id}/attest Record a connection's native-tax-disabled attestation Record your confirmation that native tax collection is disabled on the connected platform, satisfying the native-tax L2 readiness check. A new attestation overwrites any prior one. Returns 400 if your credential has no associated email. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: text (string, required) - Verbatim wording of the attestation the customer agreed to. Response fields: isConfirmed (boolean, required) - Whether a native-tax-disabled attestation has been recorded. confirmedBy (string) - Display name (or email) of the confirming user; `null` if unconfirmed. confirmedAt (string) - Timestamp the attestation was recorded; `null` if unconfirmed. text (string) - Verbatim wording the customer agreed to; `null` if unconfirmed. Response statuses: 200, 400, 401, 403, 404, 422 --- # Confirm collected-tax mode for registrations on a connection POST /connections/{conn_id}/confirm-collecting Source: https://docs.trykintsugi.com/reference/2026-10-06/confirm-collected-tax-mode-for-registrations-on-a-connection POST /connections/{conn_id}/confirm-collecting Confirm collected-tax mode for registrations on a connection Confirm collected-tax mode for the given registrations on a connection. Only pending or fix-issues registrations are affected; the rest are ignored. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: registrationIds (string[], required) - Registration ids to confirm as collecting for this connection. Only pending or fix-issues registrations are affected; the rest are ignored. requestId (string) - Optional client-generated id for this confirm attempt (a UUID or a short slug), stored on the audit trail so a later read can tell repeated confirms apart. Response statuses: 204, 400, 401, 403, 404, 422 --- # Deactivate a connection POST /connections/{conn_id}/deactivate Source: https://docs.trykintsugi.com/reference/2026-10-06/deactivate-a-connection POST /connections/{conn_id}/deactivate Deactivate a connection Set a connection's status to INACTIVE. A no-op that returns the connection unchanged if it is already INACTIVE. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if tearing down the connection's webhook subscription fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Disable tax collection on a connection POST /connections/{conn_id}/disable-tax-collection Source: https://docs.trykintsugi.com/reference/2026-10-06/disable-tax-collection-on-a-connection POST /connections/{conn_id}/disable-tax-collection Disable tax collection on a connection Disable tax calculation (L2) on a connection. A no-op that returns the connection's settings unchanged if it is already disabled. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if a per-connector tax-teardown call fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. taxCollectionEnabled (boolean, required) - Whether tax calculation is enabled on this connection. defaultCountry (string) - Default tax country for this connection (ISO 3166-1 alpha-2); `null` when unset. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types this connection syncs. `null` for every non-NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor for this Airwallex connection, as YYYY-MM-DD. `null` for every non-Airwallex connection, or when unset. woocommerceHistoricalSyncStartDate (string) - Import floor for this WooCommerce connection, as YYYY-MM-DD. `null` for every non-WooCommerce connection, or when unset. netsuiteHistoricalSyncStartDate (string) - Import floor for this NetSuite connection, as YYYY-MM-DD. `null` for every non-NetSuite connection, or when unset. microsoftD365HistoricalSyncStartDate (string) - Import floor for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. `null` for every non-D365 connection, or when unset. amazonHistoricalSyncStartDate (string) - Import floor for this Amazon connection, as YYYY-MM-DD. `null` for every non-Amazon connection, or when unset. netsuiteAccountId (string) - NetSuite account id captured from Vault on (re)connect. `null` for every non-NetSuite connection, or when unset. netsuiteSubsidiaryId (string) - NetSuite subsidiary id captured from Vault on (re)connect. `null` for every non-NetSuite connection, or when unset. [truncated, see the reference page] --- # Enable tax collection on a connection POST /connections/{conn_id}/enable-tax-collection Source: https://docs.trykintsugi.com/reference/2026-10-06/enable-tax-collection-on-a-connection POST /connections/{conn_id}/enable-tax-collection Enable tax collection on a connection Enable tax calculation (L2) on a connection. A no-op that returns the connection's settings unchanged if it is already enabled. Returns 400 if the connection is not ready for tax calculation or has opted out of tax collection. Returns 403 if the connection is an Ordway connection your credential is not permitted to enable L2 on. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if a per-connector tax-provisioning call fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. taxCollectionEnabled (boolean, required) - Whether tax calculation is enabled on this connection. defaultCountry (string) - Default tax country for this connection (ISO 3166-1 alpha-2); `null` when unset. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types this connection syncs. `null` for every non-NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor for this Airwallex connection, as YYYY-MM-DD. `null` for every non-Airwallex connection, or when unset. woocommerceHistoricalSyncStartDate (string) - Import floor for this WooCommerce connection, as YYYY-MM-DD. `null` for every non-WooCommerce connection, or when unset. netsuiteHistoricalSyncStartDate (string) - Import floor for this NetSuite connection, as YYYY-MM-DD. `null` for every non-NetSuite connection, or when unset. microsoftD365HistoricalSyncStartDate (string) - Import floor for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. `null` for every non-D365 connection, or when unset. amazonHistoricalSyncStartDate (string) - Import floor for this Amazon connection, as YYYY-MM-DD. `null` for every non-Amazon connection, or when unset. netsuiteAccountId (string) - NetSuite account id captured from Vault on (re)connect. `null` for every non-NetSuite connection, or when unset. [truncated, see the reference page] --- # Get a connection's L2 enablement readiness GET /connections/{conn_id}/l2-readiness Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-connection-s-l2-enablement-readiness GET /connections/{conn_id}/l2-readiness Get a connection's L2 enablement readiness Aggregate L2 enablement prerequisites (premium entitlement plus the prerequisite checks) for a connection, for the enablement checklist. `checks` is empty when `isPremium` is false. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: connectionId (string, required) - The connection this readiness applies to. isPremium (boolean, required) - Whether the organization is entitled to enable L2 (premium plan or test org). When `false`, `checks` is empty. checks (L2ReadinessCheck[], required) - Every L2 enablement prerequisite check and its current status. id (string, required) - Stable identifier for this prerequisite check. type (PublicL2CheckTypeEnum, required) - Whether this check blocks enablement or only warns. allowed values: REQUIRED, RECOMMENDED status (PublicL2CheckStatusEnum, required) - Whether this check currently passes. allowed values: READY, NOT_READY metadata (L2ReadinessCheckMetadata, required) - Per-check numeric detail used to render progress (e.g. "3 of 5"). count (integer) - Current count for this check, when it applies. total (integer) - Target count for this check, when it applies. capped (boolean) - Whether `count` was capped for cost; render as `N+` when true. attestation (L2Attestation) - Native-tax-disabled attestation state; `null` when unconfirmed. isConfirmed (boolean, required) - Whether a native-tax-disabled attestation has been recorded. confirmedBy (string) - Display name (or email) of the confirming user; `null` if unconfirmed. confirmedAt (string) - Timestamp the attestation was recorded; `null` if unconfirmed. text (string) - Verbatim wording the customer agreed to; `null` if unconfirmed. Response statuses: 200, 400, 401, 403, 404, 422 --- # List a connection's unconfirmed collecting registrations GET /connections/{conn_id}/pending-states Source: https://docs.trykintsugi.com/reference/2026-10-06/list-a-connection-s-unconfirmed-collecting-registrations GET /connections/{conn_id}/pending-states List a connection's unconfirmed collecting registrations List the REGISTERED registrations on this connection awaiting a collected-tax confirmation, for the confirm-collecting modal. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Registration id. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the registration, such as `US`, `CA` or `GB`. stateName (string, required) - Jurisdiction display name. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update a connection's settings PATCH /connections/{conn_id}/settings Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-connection-s-settings PATCH /connections/{conn_id}/settings Update a connection's settings Partially update per-connector settings on a connection: `defaultCountry`, `apideckConnectionState` and `needsUpdate` apply to any connection; every other field applies only to a connection of the matching source (NetSuite, Airwallex, WooCommerce, Microsoft Dynamics 365, Amazon, or DualEntry). Only the fields you send are changed. Returns 400 if `netsuiteSyncMode` selects a cash-capable mode while the NetSuite cash-sale sync beta is off for this connection. Returns 404 if the connection does not exist, belongs to an organization your credential cannot access, or a per-connector field was sent for a connection of a different source. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: defaultCountry (string) - Default tax country to set, as an ISO 3166-1 alpha-2 code. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types to sync. Only valid for a NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor to set for this Airwallex connection, as YYYY-MM-DD. Only valid for an Airwallex connection; must not be a future date. woocommerceHistoricalSyncStartDate (string) - Import floor to set for this WooCommerce connection, as YYYY-MM-DD. Only valid for a WooCommerce connection; must not be a future date. netsuiteHistoricalSyncStartDate (string) - Import floor to set for this NetSuite connection, as YYYY-MM-DD. Only valid for a NetSuite connection; must not be a future date. microsoftD365HistoricalSyncStartDate (string) - Import floor to set for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. Only valid for a D365 connection; must not be a future date. amazonHistoricalSyncStartDate (string) - Import floor to set for this Amazon connection, as YYYY-MM-DD. Only valid for an Amazon connection; must not be a future date. netsuiteAccountId (string) - NetSuite account id to set. Only valid for a NetSuite connection. An empty string clears a previously stored id. [truncated, see the reference page] --- # Resync a connection POST /connections/{conn_id}/sync Source: https://docs.trykintsugi.com/reference/2026-10-06/resync-a-connection POST /connections/{conn_id}/sync Resync a connection Manually trigger the same sync a scheduled run performs for a connection. Runs synchronously and may take a while for a connection with many records; the response reflects the connection's state once the sync completes. A no-op that returns the connection unchanged if it is INACTIVE or has a connection error. Returns 400 if the connected platform rejects its stored credentials. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Archive an archived connection's transactions DELETE /connections/{conn_id}/transactions Source: https://docs.trykintsugi.com/reference/2026-10-06/archive-an-archived-connection-s-transactions DELETE /connections/{conn_id}/transactions Archive an archived connection's transactions Archive the transactions, and best-effort the products and customers, belonging to a connection that has already been archived. Transaction archival may finish asynchronously after this returns; products and customers are archived synchronously. Deleting a connection already triggers this automatically; use this route to retry a prior partial failure. Returns 400 if the connection is not archived. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: productsArchived (boolean, required) - Whether the connection's products were archived. `false` means a best-effort step failed and this route should be retried. customersArchived (boolean, required) - Whether the connection's customers were archived. `false` means a best-effort step failed and this route should be retried. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get a connection's collected-tax comparison GET /connections/{conn_id}/view-details Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-connection-s-collected-tax-comparison GET /connections/{conn_id}/view-details Get a connection's collected-tax comparison Calculated-vs-collected tax totals for a connection, globally and per jurisdiction, for the collecting drawer. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: calculatedTaxTotal (string, required) - Sum of `calculatedTax` across every jurisdiction below. collectedTaxTotal (string, required) - Sum of `collectedTax` across every jurisdiction below. jurisdictions (ConnectionCollectingJurisdictionDetail[], required) - Per-registration breakdown; empty when none are tracked. registrationId (string, required) - Registration id. countryCode (string, required) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. stateName (string, required) - Jurisdiction display name. dateConfirmed (string) - When collecting was confirmed; `null` if still pending. status (PublicCollectedTaxTrackingStatusEnum, required) - Collected-tax confirmation status for this registration. allowed values: NOT_COLLECTING, CONFIRMED_AND_COLLECTING, CONFIRMED_AND_NOT_COLLECTING, COLLECTING isCollecting (boolean, required) - True when `status` is COLLECTING or CONFIRMED_AND_COLLECTING. hasTaxTxnId (boolean, required) - True when a tax-collected transaction id is recorded. calculatedTax (string, required) - Kintsugi-calculated tax total for this jurisdiction. collectedTax (string, required) - Tax actually collected for this jurisdiction, per source records. Response statuses: 200, 400, 401, 403, 404, 422 --- # List credits GET /credits Source: https://docs.trykintsugi.com/reference/2026-10-06/list-credits GET /credits List credits List credits, keyset-paginated. Covers every organization your credential owns, send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to narrow to one. Filter to one registration's credits with `registrationId`. A cursor is only valid for the filters AND the organization scope it was issued under, including any selector header. Category: Credits Query parameters: registrationId (string) - Return only credits held against this registration. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Credit[], required) - The credits on this page. id (string, required) - Kintsugi's unique identifier for the credit. type (PublicCreditTypeEnum, required) - The kind of credit balance: REFUND, OVERPAYMENT, ITC, or IVT. allowed values: REFUND, OVERPAYMENT, ITC, IVT taxType (PublicTaxTypeEnum, required) - Which tax pool this credit applies to on a combined return. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE amount (string, required) - The credit's face value, as a decimal string. amountConsumed (string, required) - How much of the credit has been applied to filings. amountRemaining (string, required) - How much of the credit is still available. currency (PublicCurrencyEnum) - ISO-4217 currency code of the amounts. Every credit created through this API records one (derived from the registration); `null` appears only on legacy credits created before a currency was stored. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) startDate (string, required) - Date the credit becomes available, as YYYY-MM-DD. endDate (string) - Date the credit expires, as YYYY-MM-DD. `null` when it does not expire. registrationId (string, required) - The registration this credit is held against. organizationId (string, required) - The organization that owns the credit. Always present: a portfolio-wide list spans organizations, so a row is ambiguous without it. ossRegistrationCountryId (string) - The EU OSS member-state enrollment this credit applies to, for an EU OSS registration. `null` otherwise. createdAt (string, required) - When the credit was created, as an RFC-3339 UTC timestamp. [truncated, see the reference page] --- # Create a credit POST /credits Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-credit POST /credits Create a credit Create a credit against a registration in the given organization. `registrationId` is required and must belong to that organization. The credit `type` and `currency` are derived from the registration, an EU OSS registration produces an IVT credit in EUR (and requires `ossRegistrationCountryId`), any other supported jurisdiction produces an ITC credit in the registration country's currency. A credit for an unsupported jurisdiction is rejected. Category: Credits Request body: registrationId (string, required) - The registration to hold the credit against. amount (string, required) - The credit's face value, as a decimal string. ossRegistrationCountryId (string) - The EU OSS member-state enrollment the credit applies to. Required for an EU OSS registration; leave `null` otherwise. endDate (string) - Date the credit expires, as YYYY-MM-DD. `null` for a credit that does not expire. comment (string) - An optional free-text note stored with the credit. Response fields: id (string, required) - Kintsugi's unique identifier for the credit. type (PublicCreditTypeEnum, required) - The kind of credit balance: REFUND, OVERPAYMENT, ITC, or IVT. allowed values: REFUND, OVERPAYMENT, ITC, IVT taxType (PublicTaxTypeEnum, required) - Which tax pool this credit applies to on a combined return. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE amount (string, required) - The credit's face value, as a decimal string. amountConsumed (string, required) - How much of the credit has been applied to filings. amountRemaining (string, required) - How much of the credit is still available. currency (PublicCurrencyEnum) - ISO-4217 currency code of the amounts. Every credit created through this API records one (derived from the registration); `null` appears only on legacy credits created before a currency was stored. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) startDate (string, required) - Date the credit becomes available, as YYYY-MM-DD. endDate (string) - Date the credit expires, as YYYY-MM-DD. `null` when it does not expire. registrationId (string, required) - The registration this credit is held against. [truncated, see the reference page] --- # List customers GET /customers Source: https://docs.trykintsugi.com/reference/2026-10-06/list-customers GET /customers List customers List customers, keyset-paginated. Covers every organization your credential can access; pass an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page; Archived customers are excluded. `hasMore` and `hasPrevious` report whether a page exists that way. A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Customers Query parameters: sort (PublicCustomerSortEnum) - Field to sort by. `createdAt` is the default and is dramatically faster on large organizations; the other keys sort the whole matching set. allowed values: createdAt, name, street1, city, state, postalCode, country, status order (PublicCustomerSortOrder) - Sort direction. Defaults to `desc`, so newest first. allowed values: asc, desc search (string) - Search over customer id, name, email, externalId and externalFriendlyId. id, externalId and externalFriendlyId must match exactly; name and email match a case-insensitive substring. country (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any of them. state (string) - Comma-separated state or province codes; matches any of them. source (string) - Comma-separated source systems; matches any of them. connectionId (string) - Comma-separated connection ids; matches any of them. This filters rows by connection. To restrict which organization is read, send the `Connection-Id` header instead. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Customer[], required) - The customers on this page. id (string, required) - Kintsugi's unique identifier for the customer. organizationId (string, required) - Organization the customer belongs to. Send it as the `Organization-Id` header to scope a write to this customer's organization. externalId (string) - Your stable identifier for the customer. `null` when the source system supplied none. externalFriendlyId (string) - Human-facing identifier from the source system. `null` when the source has only externalId. name (string) - Customer name. [truncated, see the reference page] --- # Create a customer POST /customers Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-customer POST /customers Create a customer Create a customer in the resolved organization. Idempotent on `externalId` and `source`, and additionally on `connectionId` when you send one: sending the same values again returns the existing customer unchanged and responds `200` instead of creating a duplicate. The customer is not updated by this call; use `PATCH /customers/{customerId}` to update. Omitting `connectionId` matches an existing customer with that `externalId` and `source` whatever its connection. If the match is a customer you previously deleted, it is restored (not duplicated) so its transactions and exemptions stay attached to it. A new customer is always `ACTIVE`; delete one with `DELETE`. Category: Customers Request body: externalId (string) - Your stable identifier for the customer, and the key creating is idempotent on. Sending one that already exists for the same source and connection returns that customer unchanged with 200 instead of creating a second one; use PATCH to update it. name (string) - Customer name. companyName (string) - Registered or legal business name, when it differs from name. email (string) - Contact email address. phone (string) - Contact phone number. connectionId (string) - Connection to attribute the customer to. Must belong to the resolved organization. Part of the idempotency key. externalFriendlyId (string) - Human-facing identifier from the source system, shown in place of externalId when the source has both. source (string) - Origin system of the customer (e.g. API, SHOPIFY). Defaults to OTHER. Must be a supported public source; unsupported values are rejected. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) taxRegistrations (CustomerTaxRegistrationWrite[]) - Tax registrations to record for the customer, each keyed by (countryCode, taxType). Repeating a pair in one request is rejected. countryCode (string, required) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Part of the registration's identity: a customer has one registration per (countryCode, taxType) pair. taxType (PublicCustomerTaxTypeEnum, required) - Kind of tax the registration is for. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown [truncated, see the reference page] --- # Get a customer by id GET /customers/{customer_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-customer-by-id GET /customers/{customer_id} Get a customer by id Fetch a single customer by id. Returns 404 if the customer does not exist, is archived, or belongs to an organization your credential cannot access. A customer you cannot access and one that does not exist return the same 404, so the API never confirms an id exists. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Response fields: id (string, required) - Kintsugi's unique identifier for the customer. organizationId (string, required) - Organization the customer belongs to. Send it as the `Organization-Id` header to scope a write to this customer's organization. externalId (string) - Your stable identifier for the customer. `null` when the source system supplied none. externalFriendlyId (string) - Human-facing identifier from the source system. `null` when the source has only externalId. name (string) - Customer name. companyName (string) - Registered or legal business name. email (string) - Contact email address. phone (string) - Contact phone number. status (PublicCustomerStatusEnum, required) - Customer status. Reads never return archived customers, so this is always `ACTIVE`. allowed values: ACTIVE, ARCHIVED addressStatus (PublicCustomerAddressStatusEnum, required) - How far address validation got for this customer. UNVERIFIED until validation has run; BLANK when there is no address to validate. allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK registrationNumber (string) - Business registration number, or `null` when Kintsugi has not captured one for this customer. source (string, required) - Origin system of the customer (e.g. API, SHOPIFY). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) connectionId (string) - Connection that produced the customer. `null` when the customer was not produced by a connection (e.g. created through this API). street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. [truncated, see the reference page] --- # Update a customer PATCH /customers/{customer_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-customer PATCH /customers/{customer_id} Update a customer Update a customer in the resolved organization. Only the fields you send are applied. Sending any address field resets `addressStatus` to `UNVERIFIED`; the new address is validated the next time the customer is processed, not during this call. `taxRegistrations` upserts each entry on its `(countryCode, taxType)` pair and leaves unlisted registrations alone; it cannot remove one. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Request body: name (string) - Customer name. Omit to leave unchanged; send a value to replace; send `null` to clear. companyName (string) - Registered or legal business name. Omit to leave unchanged; send a value to replace; send `null` to clear. email (string) - Contact email address. Omit to leave unchanged; send a value to replace; send `null` to clear. phone (string) - Contact phone number. Omit to leave unchanged; send a value to replace; send `null` to clear. street1 (string) - First line of the street address. Omit to leave unchanged; send a value to replace; send `null` to clear. street2 (string) - Second line of the street address. Omit to leave unchanged; send a value to replace; send `null` to clear. city (string) - City or locality. Omit to leave unchanged; send a value to replace; send `null` to clear. county (string) - County or district. Omit to leave unchanged; send a value to replace; send `null` to clear. state (string) - State or province code. Omit to leave unchanged; send a code to replace; send `null` to clear. postalCode (string) - Postal or ZIP code. Omit to leave unchanged; send a value to replace; send `null` to clear. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Omit to leave unchanged; send a code to replace; send `null` to clear. taxRegistrations (CustomerTaxRegistrationWrite[]) - Tax registrations to upsert, each keyed by (countryCode, taxType). Registrations you do not list are left unchanged, and omitting the field touches none. This field cannot remove a registration. countryCode (string, required) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Part of the registration's identity: a customer has one registration per (countryCode, taxType) pair. [truncated, see the reference page] --- # Archive a customer DELETE /customers/{customer_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/archive-a-customer DELETE /customers/{customer_id} Archive a customer Delete a customer. It is removed from this API: afterwards it is absent from `GET /customers` and returns 404 from every read and write, exactly as a customer that never existed does. Creating a customer again with the same `externalId` and `source` restores this one instead of making a second, so its transactions and exemptions stay attached to it. Returns 404 if the customer does not exist, is already deleted, or belongs to an organization your credential cannot access. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Upsert a customer tax registration by tax id POST /customers/{customer_id}/tax-registrations Source: https://docs.trykintsugi.com/reference/2026-10-06/upsert-a-customer-tax-registration-by-tax-id POST /customers/{customer_id}/tax-registrations Upsert a customer tax registration by tax id Create or update a tax registration. Send `countryCode` and `taxType` together to validate `taxId` against that pair; omit both to derive from `taxId` and the customer's country. Always `200`. `400` if `taxId` is invalid, mismatched, or only one field is sent. `404` if the customer doesn't exist. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Request body: taxId (string, required) - The tax registration number. When countryCode and taxType are both omitted, they are derived from this value together with the customer's own country. countryCode (string) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Send this together with taxType to validate taxId against an explicit pair instead of deriving one. taxType (PublicCustomerTaxTypeEnum) - Kind of tax the registration is for. Send this together with countryCode. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown Response fields: id (string, required) - Kintsugi's unique identifier for the registration. countryCode (string, required) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. taxType (PublicCustomerTaxTypeEnum, required) - Kind of tax the registration is for. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown taxId (string, required) - The tax registration number itself. isValid (boolean, required) - Whether the tax id passed validation for its country and type. Derived by Kintsugi; not accepted on write. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Dashboard task counts GET /dashboard/tasks Source: https://docs.trykintsugi.com/reference/2026-10-06/dashboard-task-counts GET /dashboard/tasks Dashboard task counts Counts of registrations, filings, products, addresses, connections, and related work items for the organization selected by Organization-Id, Connection-Id, or Entity-Id. Category: Experience Response fields: registrationsRegimeToChange (integer, required) - Registrations whose tax regime must be updated before filing. registrationsRegimeToAcknowledge (integer, required) - Registrations with a regime change the org has not acknowledged. registrationsToFinish (integer, required) - In-progress registrations that still need setup steps. reviewInternationalExposure (integer) - Jurisdictions with international nexus exposure to review. currentFilingsToApprove (integer, required) - Current-period filings awaiting customer approval. backfilingsToApprove (integer, required) - Back filings awaiting customer approval. pendingProduct (integer, required) - Products missing classification or tax configuration. invalidAddresses (integer, required) - Addresses that failed validation and need correction. blankAddresses (integer, required) - Addresses missing required fields. needsUpdateConnectionsCount (integer, required) - Connections that need reauthorization or configuration updates. expiredExemptionsCount (integer, required) - Customer exemptions that have expired. missingCertificatesCount (integer) - Exemptions missing required certificate documentation. needsTaxCollectionEnableConnectionsCount (integer, required) - Connections where tax collection should be enabled in the source system. readOnlySourcesToEnableTaxCollectionCount (integer, required) - Read-only connections that still need tax collection enabled at the source. iorNumbersToSubmit (integer) - Importer-of-record numbers the org must submit. proposalsToReview (integer) - Pending proposals awaiting accept or decline. Response statuses: 200, 400, 401, 404, 422 --- # List exemption requests GET /exemption-requests Source: https://docs.trykintsugi.com/reference/2026-10-06/list-exemption-requests GET /exemption-requests List exemption requests List exemption requests, newest first. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Optional `status` filters by lifecycle status, and optional `jurisdiction` (a two-letter US state code) returns only requests that include it. Returns an empty list when there are no matching requests. Category: Exemption Requests Query parameters: status (string) - Filter by lifecycle status; returns only requests in that status. jurisdiction (string) - Two-letter US state code. Returns only requests whose jurisdictions include this state. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. allowed values: PENDING, SENT, FAILED expiresAt (string, required) - When the customer's upload link expires, as an RFC-3339 UTC timestamp. createdAt (string, required) - When the request was created, as an RFC-3339 UTC timestamp. [truncated, see the reference page] --- # Create an exemption request POST /exemption-requests Source: https://docs.trykintsugi.com/reference/2026-10-06/create-an-exemption-request POST /exemption-requests Create an exemption request Create an exemption-certificate request in the resolved organization and email the customer at `customerEmail` a link to upload their certificate. `customerId` links the request to a customer in that organization. Returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management. The returned request starts in status `SENT` with every jurisdiction `PENDING_NO_SUBMISSION`. Category: Exemption Requests Request body: customerId (string, required) - Kintsugi customer id to link the request to, in the resolved organization. customerEmail (string, required) - Email address the exemption-request email is sent to. jurisdictions (string[], required) - Uppercase two-letter US state codes the certificate is requested for. notesForCustomer (string) - Optional note included in the email to the customer. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. [truncated, see the reference page] --- # Get pre-send exemption-request conflicts for a customer GET /exemption-requests/conflicts Source: https://docs.trykintsugi.com/reference/2026-10-06/get-pre-send-exemption-request-conflicts-for-a-customer GET /exemption-requests/conflicts Get pre-send exemption-request conflicts for a customer Return per-state warnings for a customer before you create a request: an active certificate, an open request, or an in-review certificate. Non-blocking advice a client can surface before sending. Searched across every organization your credential owns, so no selector is needed for a known customer. Returns an empty list when there are no conflicts, and 404 if the customer does not exist or belongs to an organization your credential cannot access. Category: Exemption Requests Query parameters: customerId (string, required) - The customer to check for conflicts. Response fields: state (string, required) - Two-letter US state code the warnings apply to. warnings (string[], required) - Human-readable warnings for this state (an active certificate, an open request, or an in-review certificate). Non-blocking. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List an exemption request's certificates GET /exemption-requests/{request_id}/certificates Source: https://docs.trykintsugi.com/reference/2026-10-06/list-an-exemption-request-s-certificates GET /exemption-requests/{request_id}/certificates List an exemption request's certificates List the certificates uploaded against one exemption request, newest first. Searched across every organization your credential owns, so no selector is needed for a known request. Returns an empty list when the request has no certificates, and 404 if the request does not exist or belongs to an organization your credential cannot access. Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate document. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the file. reviewStatus (PublicCertificateReviewStatusEnum, required) - Review status of the certificate. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED uploadedAt (string, required) - When the certificate was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Mark an exemption request completed POST /exemption-requests/{request_id}/mark-completed Source: https://docs.trykintsugi.com/reference/2026-10-06/mark-an-exemption-request-completed POST /exemption-requests/{request_id}/mark-completed Mark an exemption request completed Manually close a request: set its status to `COMPLETED`, record the closure, and immediately expire the customer's upload link. Idempotent — closing an already-completed request returns it unchanged. Returns the updated request. Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. allowed values: PENDING, SENT, FAILED expiresAt (string, required) - When the customer's upload link expires, as an RFC-3339 UTC timestamp. createdAt (string, required) - When the request was created, as an RFC-3339 UTC timestamp. resentAt (string, required) - When the request's upload link was last resent, or null if it has not been resent. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Resend an exemption request's upload link POST /exemption-requests/{request_id}/resend Source: https://docs.trykintsugi.com/reference/2026-10-06/resend-an-exemption-request-s-upload-link POST /exemption-requests/{request_id}/resend Resend an exemption request's upload link Mint a fresh upload link, extend it for another 60 days, email it to the customer, and return the updated request. Allowed once per request, and only while the request is partially completed; the status is unchanged. Send an optional `notesForCustomer` in the body to replace the note in the resend email (a `null` clears it); omit the body to reuse the request's stored note. Returns 409 if the request is ineligible or has already been resent, 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management, and 503 if the email could not be sent (the request is left resendable). Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Request body: notesForCustomer (string) - Optional note to include in the resend email. When present it replaces the request's stored note (send `null` to clear it); omit the field entirely to reuse the note from the original request. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. [truncated, see the reference page] --- # Send an exemption-request reminder POST /exemption-requests/{request_id}/send-reminder Source: https://docs.trykintsugi.com/reference/2026-10-06/send-an-exemption-request-reminder POST /exemption-requests/{request_id}/send-reminder Send an exemption-request reminder Email the customer a reminder for a request that is still awaiting a response, and return the (unchanged) request. The reminder does not change the request's status, expiry, or per-jurisdiction progress. Returns 409 if the request is not in a status that allows a reminder, has expired, or predates regenerable upload links. Returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management, and 503 if the reminder email could not be sent (the request is left unchanged). Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. allowed values: PENDING, SENT, FAILED expiresAt (string, required) - When the customer's upload link expires, as an RFC-3339 UTC timestamp. [truncated, see the reference page] --- # List exemptions GET /exemptions Source: https://docs.trykintsugi.com/reference/2026-10-06/list-exemptions GET /exemptions List exemptions List exemptions, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Filter to one customer's exemptions with `customerId`, and to a country, jurisdiction, validity start or end date, connection, or a customer name / email substring with the matching parameter. Pass `sort` and `order` to order the list; omit `sort` to keep the default order. `sort=customerName` orders by the owning customer's name. Pass `expand=customer` to embed the owning customer's `companyName` and `customerName` under `customer` on each row. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page; `hasMore` and `hasPrevious` report whether a page exists that way. Archived exemptions are excluded. A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. `expand` does not affect which exemptions are returned, so a cursor stays valid whether or not you pass it. Category: Exemptions Query parameters: sort (PublicExemptionSortEnum) - Field to sort by. Omit to keep the default ordering. `customerName` orders by the owning customer's name, resolved server-side. allowed values: country, jurisdiction, customerName, startDate, endDate, status order (PublicExemptionSortOrder) - Sort direction. Applies only when `sort` is set. Defaults to `asc`. allowed values: asc, desc customerId (string) - Comma-separated customer ids; matches any of them. This is how you read one customer's exemptions. transactionId (string) - Comma-separated transaction ids; matches any of them. status (string) - Comma-separated lifecycle statuses; matches any of them. ARCHIVED is never returned and is rejected here. exemptionType (string) - Comma-separated exemption types; matches any of them. country (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any of them. jurisdiction (string) - State or province code the exemption is scoped to. startDate (string) - Match exemptions whose validity start date is this date. endDate (string) - Match exemptions whose validity end date is this date. search (string) - Match an exact exemption id, or a customer name or email substring. [truncated, see the reference page] --- # Create an exemption POST /exemptions Source: https://docs.trykintsugi.com/reference/2026-10-06/create-an-exemption POST /exemptions Create an exemption Create an exemption in the resolved organization. `customerId` is required and must belong to that organization; so must `transactionId` when you send one. `source` is not accepted on the body: an exemption created through this API is always recorded with source API. ARCHIVED is not an accepted `status` here; an archived exemption is absent from every read on this API. Category: Exemptions Request body: exemptionType (PublicExemptionTypeEnum, required) - What the exemption applies to. allowed values: customer, wholesale, transaction, reverse_charge, partial certificateType (string) - Partial-exemption form code, such as CDTFA-230-M. Required when `exemptionType` is `partial`. Omit it for every other type. startDate (string, required) - First day the exemption is in force, as YYYY-MM-DD. endDate (string) - Last day the exemption is in force, as YYYY-MM-DD. Omit it, or send `null`, for an exemption that does not expire. Must not precede `startDate`. countryCode (string) - ISO 3166-1 alpha-2 country code to scope the exemption to, such as `US`, `CA` or `GB`. An unrecognized code returns 400. jurisdiction (string) - State or province code to scope the exemption to. Validated against `countryCode` when you send both; an unrecognized pair returns 400. reseller (boolean) - Whether the exemption is claimed on the basis of resale. fein (string) - Federal Employer Identification Number to record. salesTaxId (string) - Sales tax registration number to record. status (PublicExemptionWriteStatusEnum) - Lifecycle status to create the exemption with. Defaults to ACTIVE, which is the only status tax calculation applies. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED customerId (string, required) - Customer to hold the exemption against. Must belong to the resolved organization; one that does not returns 400. transactionId (string) - Transaction to apply the exemption to. Must belong to the resolved organization; one that does not returns 400. Omit it to exempt the customer's transactions generally. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption. organizationId (string, required) - Organization the exemption belongs to. Send it as `Organization-Id` to scope a request to this exemption. [truncated, see the reference page] --- # Create many exemptions POST /exemptions/bulk Source: https://docs.trykintsugi.com/reference/2026-10-06/create-many-exemptions POST /exemptions/bulk Create many exemptions Create between 1 and 100 exemptions in the resolved organization in one request. The batch is all-or-nothing: every entry is validated first, and if any one is invalid the whole request returns 400 identifying the offending entry's index and nothing is created. Each entry follows the same rules as `POST /exemptions`: `customerId` is required and must belong to the organization, as must `transactionId` when sent, and `source` is always recorded as API. A `partial` exemption is not accepted here; create it with `POST /exemptions`. An empty list, or more than 100 entries, returns 400. Category: Exemptions Request body: exemptions (ExemptionCreate[], required) - The exemptions to create, between 1 and 100. They are created all-or-nothing: if any one is invalid the whole request fails and none are created. Each entry has the same shape as the body of `POST /exemptions`. exemptionType (PublicExemptionTypeEnum, required) - What the exemption applies to. allowed values: customer, wholesale, transaction, reverse_charge, partial certificateType (string) - Partial-exemption form code, such as CDTFA-230-M. Required when `exemptionType` is `partial`. Omit it for every other type. startDate (string, required) - First day the exemption is in force, as YYYY-MM-DD. endDate (string) - Last day the exemption is in force, as YYYY-MM-DD. Omit it, or send `null`, for an exemption that does not expire. Must not precede `startDate`. countryCode (string) - ISO 3166-1 alpha-2 country code to scope the exemption to, such as `US`, `CA` or `GB`. An unrecognized code returns 400. jurisdiction (string) - State or province code to scope the exemption to. Validated against `countryCode` when you send both; an unrecognized pair returns 400. reseller (boolean) - Whether the exemption is claimed on the basis of resale. fein (string) - Federal Employer Identification Number to record. salesTaxId (string) - Sales tax registration number to record. status (PublicExemptionWriteStatusEnum) - Lifecycle status to create the exemption with. Defaults to ACTIVE, which is the only status tax calculation applies. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED customerId (string, required) - Customer to hold the exemption against. Must belong to the resolved organization; one that does not returns 400. [truncated, see the reference page] --- # List customers missing certificates GET /exemptions/missing-certificates Source: https://docs.trykintsugi.com/reference/2026-10-06/list-customers-missing-certificates GET /exemptions/missing-certificates List customers missing certificates List the customers who hold an active exemption with no certificate on file, keyset-paginated and sorted by exposure (US exempt sales at risk) with an alphabetical tiebreak, highest first. Scoped to one organization: send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or omit it if your credential owns exactly one. Filter to one state with `jurisdiction`. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page. A cursor is only valid for the `jurisdiction` filter, the `limit`, and the organization it was issued under; change any of those and start from the first page. Category: Exemptions Query parameters: jurisdiction (string) - Filter to one state or province code, e.g. `CA`. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (MissingCertificateCustomer[], required) - The customers on this page, highest exposure first. customerId (string, required) - Kintsugi's unique identifier for the customer. customerName (string) - Customer's name. An empty string when none is on file. customerEmail (string) - Customer's email. An empty string when none is on file, in which case a bulk send skips them (there is nowhere to send the request). uncoveredCount (integer, required) - How many of the customer's active exemptions have no certificate. totalAmount (string, required) - Total exempt sales at risk across the customer's uncertified jurisdictions, as a decimal string. This is the field the list is sorted by, highest first. currency (PublicCurrencyEnum, required) - ISO-4217 currency the exposure amount is in. Always USD: missing-certificate tracking covers US exempt sales only. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) exemptions (MissingCertificateExemption[], required) - The customer's uncertified exemptions. exemptionId (string, required) - Kintsugi's unique identifier for the uncertified exemption. jurisdiction (string) - State or province code the exemption is scoped to. `null` when it covers the whole country. [truncated, see the reference page] --- # Send missing-certificate requests POST /exemptions/missing-certificates/bulk-send Source: https://docs.trykintsugi.com/reference/2026-10-06/send-missing-certificate-requests POST /exemptions/missing-certificates/bulk-send Send missing-certificate requests Email a missing-certificate request to each named customer, bundling all of their uncertified jurisdictions into one request per customer. Scoped to one organization the same way as the list. A customer with no email, or no uncertified exemptions, is skipped and reported in `skippedReasons`. Returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management. Category: Exemptions Request body: customerIds (string[], required) - Customers to email, between 1 and 100. Each gets one request bundling all of their uncertified jurisdictions. Response fields: sent (integer, required) - How many requests were created and emailed. skipped (integer, required) - How many customers were not sent a request. skippedReasons (MissingCertificateBulkSendSkipped[], required) - One entry per skipped customer. Empty when none were skipped. customerId (string, required) - The customer that was skipped. reason (PublicMissingCertificateSkipReasonEnum, required) - Why the customer was skipped. allowed values: missing_email, no_uncertified_exemptions Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Missing-certificate metrics GET /exemptions/missing-certificates/metrics Source: https://docs.trykintsugi.com/reference/2026-10-06/missing-certificate-metrics GET /exemptions/missing-certificates/metrics Missing-certificate metrics Summarize a single organization's missing-certificate exposure: how many active exemptions lack a certificate, how many active exemptions there are in total, how many customers are affected, and the total US exempt sales at risk. Scoped to one organization the same way as the list. All counts are zero and the amount is `0.00` when nothing is uncertified. Category: Exemptions Response fields: uncoveredCount (integer, required) - Active exemptions with no certificate on file. totalActiveCount (integer, required) - All active exemptions, certified or not. customersAffected (integer, required) - Distinct customers with at least one uncertified exemption. totalAmount (string, required) - Total exempt sales at risk across every uncertified exemption, as a decimal string. currency (PublicCurrencyEnum, required) - ISO-4217 currency the exposure amount is in. Always USD: missing-certificate tracking covers US exempt sales only. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Upload a certificate for a customer POST /exemptions/missing-certificates/{customer_id}/upload Source: https://docs.trykintsugi.com/reference/2026-10-06/upload-a-certificate-for-a-customer POST /exemptions/missing-certificates/{customer_id}/upload Upload a certificate for a customer Upload a certificate on a customer's behalf, as `multipart/form-data` with the file in the `file` part, to cover their uncertified jurisdictions. The file must be a PDF, PNG or JPG and at most 10 MB. Creates one validation job per uncovered exemption and returns 202 with an `uploadSessionId`; poll `GET /exemptions/missing-certificates/{customerId}/upload-status/{uploadSessionId}` for per-jurisdiction results. Scoped to one organization the same way as the list. Returns 404 if the customer has no uncovered exemptions in an organization your credential can access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Exemptions Path parameters: customer_id (string, required) - The customer whose uncovered exemptions this upload targets. Response fields: uploadSessionId (string, required) - Poll `GET /exemptions/missing-certificates/{customerId}/upload-status/{uploadSessionId}` with this for per-jurisdiction results. certificateImportIds (string[], required) - One import id per uncovered exemption the upload targets. status (PublicMissingCertificateStatusEnum) - Always PROCESSING at acceptance; poll the status endpoint for results. allowed values: PROCESSING, SATISFIED, REJECTED Response statuses: 202, 400, 401, 403, 404, 413, 422 --- # Poll a customer's certificate upload status GET /exemptions/missing-certificates/{customer_id}/upload-status/{upload_session_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/poll-a-customer-s-certificate-upload-status GET /exemptions/missing-certificates/{customer_id}/upload-status/{upload_session_id} Poll a customer's certificate upload status Return the per-exemption validation status for a customer's certificate upload session. Each result carries a `reason` when its exemption was rejected. Scoped to one organization the same way as the list. Returns 404 if the upload session does not exist for this customer in an organization your credential can access. Category: Exemptions Path parameters: customer_id (string, required) - The customer whose upload to check. upload_session_id (string, required) - The upload session id returned by the upload endpoint. Response fields: uploadSessionId (string, required) - The upload session these results belong to. status (PublicMissingCertificateStatusEnum, required) - Overall status: PROCESSING while any exemption is still validating, SATISFIED when at least one certificate was accepted, REJECTED otherwise. allowed values: PROCESSING, SATISFIED, REJECTED reason (string) - Why the whole upload was rejected, such as the certificate matching no uncertified jurisdiction. `null` unless the upload as a whole was rejected. results (MissingCertificateJurisdictionResult[], required) - Per-exemption validation results. certificateImportId (string, required) - Kintsugi's identifier for this exemption's import job. exemptionId (string) - The exemption this result applies to, or `null` when the import could not be matched to one. status (PublicMissingCertificateStatusEnum, required) - Validation status for this exemption. allowed values: PROCESSING, SATISFIED, REJECTED reason (string) - Why this exemption was rejected. Present only when `status` is REJECTED; `null` otherwise. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get an exemption by id GET /exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-an-exemption-by-id GET /exemptions/{exemption_id} Get an exemption by id Fetch a single exemption by id. Searched across every organization your credential owns, so no selector is needed for a known id. Pass `expand=customer` to embed the owning customer's `companyName` and `customerName` under `customer`. Returns 404 if the exemption does not exist, is archived, or belongs to an organization your credential cannot access, so the API never confirms an id exists. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Query parameters: expand (ExemptionExpand[]) - Relations to embed. Pass `customer` to embed the owning customer's `companyName` and `customerName` under `customer`; omitted otherwise. allowed values: customer Response fields: id (string, required) - Kintsugi's unique identifier for the exemption. organizationId (string, required) - Organization the exemption belongs to. Send it as `Organization-Id` to scope a request to this exemption. customerId (string) - Customer the exemption is held against. `null` for an exemption recorded against a transaction alone. customerName (string) - Display name of the customer the exemption is held against, resolved when you list or fetch an exemption. `null` for an exemption recorded against a transaction alone (no customer). Sort a list by it with `sort=customerName`. transactionId (string) - Transaction the exemption applies to. `null` when it applies to the customer's transactions generally rather than to one of them. exemptionType (PublicExemptionTypeEnum, required) - What the exemption applies to. allowed values: customer, wholesale, transaction, reverse_charge, partial certificateType (string) - Partial-exemption form code, such as CDTFA-230-M. Required when `exemptionType` is `partial`. Null for every other exemption type. status (PublicExemptionStatusEnum, required) - Lifecycle status. Only ACTIVE exemptions are applied by tax calculation; the others are retained for reporting. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED countryCode (string) - ISO 3166-1 alpha-2 country code the exemption is scoped to, such as `US`, `CA` or `GB`. `null` when it is not scoped to one country. jurisdiction (string) - State or province code the exemption is scoped to, within `countryCode`. `null` when it covers the whole country. [truncated, see the reference page] --- # Update an exemption PATCH /exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-an-exemption PATCH /exemptions/{exemption_id} Update an exemption Update an exemption in the resolved organization. Only the fields you send are applied; send `endDate` as `null` to remove an expiry. `customerId`, `exemptionType`, `countryCode` and `jurisdiction` cannot be changed, since they define which exemption this is: create a new exemption instead. An exemption that is or becomes ACTIVE has the transactions it covers requeued for tax recalculation, which happens after this call returns. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Request body: startDate (string) - First day the exemption is in force, as YYYY-MM-DD. Omit or send `null` to leave unchanged. endDate (string) - Last day the exemption is in force, as YYYY-MM-DD. Omit to leave unchanged. Send `null` to remove the expiry. Must not precede the exemption's `startDate`. reseller (boolean) - Whether the exemption is claimed on the basis of resale. Omit or send `null` to leave unchanged; send `true` or `false` to replace. fein (string) - Federal Employer Identification Number to record. Omit or send `null` to leave unchanged; send a value to replace. This PATCH cannot clear a stored FEIN. salesTaxId (string) - Sales tax registration number to record. Omit or send `null` to leave unchanged; send a value to replace. This PATCH cannot clear a stored sales tax id. status (PublicExemptionWriteStatusEnum) - Lifecycle status to move the exemption to. Only ACTIVE exemptions are applied by tax calculation. Omit or send `null` to leave unchanged. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption. organizationId (string, required) - Organization the exemption belongs to. Send it as `Organization-Id` to scope a request to this exemption. customerId (string) - Customer the exemption is held against. `null` for an exemption recorded against a transaction alone. customerName (string) - Display name of the customer the exemption is held against, resolved when you list or fetch an exemption. `null` for an exemption recorded against a transaction alone (no customer). Sort a list by it with `sort=customerName`. [truncated, see the reference page] --- # Archive an exemption DELETE /exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/archive-an-exemption DELETE /exemptions/{exemption_id} Archive an exemption Archive an exemption in the resolved organization. Archiving is a soft delete: the exemption is retained but removed from this API, so afterwards it is absent from `GET /exemptions` and returns 404 from every read and write, and it stops being applied by tax calculation. Returns 404 if the exemption does not exist, is already archived, or belongs to an organization your credential cannot access. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Upload an exemption certificate POST /exemptions/{exemption_id}/certificates Source: https://docs.trykintsugi.com/reference/2026-10-06/upload-an-exemption-certificate POST /exemptions/{exemption_id}/certificates Upload an exemption certificate Attach a certificate document to an exemption in the resolved organization, as `multipart/form-data` with the file in the `file` part. The file must be a PDF and at most 10 MB. Returns the stored certificate's metadata; fetch its bytes with `GET /exemptions/{exemptionId}/certificates/{certificateId}`. Returns 404 if the exemption does not exist, is archived, or belongs to an organization your credential cannot access. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate document. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the file. fileSizeBytes (integer, required) - Size of the file in bytes. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422 --- # Download an exemption certificate GET /exemptions/{exemption_id}/certificates/{certificate_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/download-an-exemption-certificate GET /exemptions/{exemption_id}/certificates/{certificate_id} Download an exemption certificate Return a certificate's metadata and a short-lived URL to download its bytes. Searched across every organization your credential owns, so no selector is needed for a known id. Fetch `downloadUrl` directly with a GET; it expires after `expiresInSeconds`. Returns 404 if the exemption or the certificate does not exist, is archived, or belongs to an organization your credential cannot access, or if the certificate is not attached to this exemption. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. certificate_id (string, required) - The unique identifier of the certificate document. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate document. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the file. fileSizeBytes (integer, required) - Size of the file in bytes. downloadUrl (string, required) - Time-limited URL to download the certificate bytes. Fetch it directly with a GET; do not send your API credentials to it. It stops working after `expiresInSeconds`, so request this endpoint again for a fresh URL rather than storing it. expiresInSeconds (integer, required) - Seconds from now until `downloadUrl` stops working. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List filings GET /filings Source: https://docs.trykintsugi.com/reference/2026-10-06/list-filings GET /filings List filings List filings, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Every list filter takes a comma-separated list and matches any of the values you send. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor`/`previousCursor` to page. Pass `sort` and `order` to order the list; omit `sort` to keep the default order. None of the sort keys is index-backed, so sorting a large scope sorts the whole matching set. Pass `expand=salesBreakdown`, `expand=vatRecovery` and/or `expand=artifacts` to embed those buckets on each row; omitted otherwise. A cursor is only valid for the sort, the filters AND the organization scope it was issued under; change any of them and start again from the first page. `expand` does not affect which filings are returned, so a cursor stays valid whether or not you pass it. Filings marked do-not-file (skipped under an organization or registration do-not-file setting) are excluded from this list and from the summary counts. Category: Filings Query parameters: expand (FilingExpand[]) - Buckets to embed on each filing. `salesBreakdown` embeds the period's sales composition; `vatRecovery` embeds the EU/UK input-VAT recovery rate pair; `artifacts` embeds the filing's return/payment/additional artifacts by slot. Omitted otherwise. Does not change which filings are returned. allowed values: salesBreakdown, vatRecovery, artifacts limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. sort (PublicFilingSortEnum) - Field to sort by. Omit to keep the default (id-ordered) ordering. allowed values: status, countryCode, stateCode, startDate, endDate, dateFiled, amount, totalTaxLiability order (PublicFilingSortOrder) - Sort direction. Applies only when `sort` is set. Defaults to `asc`. allowed values: asc, desc status (string) - Comma-separated lifecycle statuses; matches any of them. countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any. stateCode (string) - Comma-separated state/province codes; matches any. filingCategory (string) - Comma-separated filing categories; matches any. taxType (string) - Comma-separated tax types; matches any. [truncated, see the reference page] --- # Request back-filings POST /filings/backFilingRequest Source: https://docs.trykintsugi.com/reference/2026-10-06/request-back-filings POST /filings/backFilingRequest Request back-filings Create unapproved BACK_FILING rows for the requested registrations and periods. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization to create them in; the periods must be within the eligible options from `GET /filings/backFilingRequest/options`. Returns 404 when back-filing is not available for the organization or a registration is not visible, 400 when a requested period is invalid or out of bounds, 403 PLAN_UPGRADE_REQUIRED when the organization is on a free plan, and 403 FORBIDDEN when the organization's plan does not include managed filings. Category: Filings Request body: requests (BackFilingRequestRegistrationInput[], required) - The registrations and periods to request back-filings for. registrationId (string, required) - The registration to back-file under. periods (BackFilingRequestPeriodInput[], required) - The periods to back-file, each within the eligible options. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. notes (string) - Optional note recorded on each created filing. Response fields: created (Filing[], required) - The BACK_FILING filings created by this request, unapproved. id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE filingCategory (string, required) - The kind of filing period: REGULAR, AMENDMENT or BACK_FILING (a legacy PREPAYMENT value may appear on historical rows). taxType (PublicTaxTypeEnum, required) - Which taxes this filing covers, from the associated registration. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing jurisdiction, such as `US`, `CA` or `GB`. stateCode (string) - State or province code, or null for a country-level filing. [truncated, see the reference page] --- # List back-filing request options GET /filings/backFilingRequest/options Source: https://docs.trykintsugi.com/reference/2026-10-06/list-back-filing-request-options GET /filings/backFilingRequest/options List back-filing request options List the registrations and open periods eligible for a customer back-filing request, across every organization your credential owns; send an `Organization-Id` selector to narrow to one. An organization with nothing eligible contributes no registrations rather than failing the read. Category: Filings Response fields: registrations (BackFilingRequestRegistrationOption[]) - Registrations with open back-filing periods across the scope. organizationId (string, required) - Organization the registration belongs to. Present so a portfolio-wide caller can attribute each option to its org. registrationId (string, required) - The eligible registration's id. stateCode (string, required) - The registration's state/jurisdiction code. remittanceTag (string) - P&I remittance timing tag, if known. periods (BackFilingRequestPeriod[]) - The open periods eligible for back-filing. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. label (string, required) - Human-readable period label. helpArticleUrl (string) - Link to the back-filing help article, if any. helpArticleLabel (string, required) - Label for the help-article link. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get the current back-filing terms GET /filings/backFilingTerms/current Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-current-back-filing-terms GET /filings/backFilingTerms/current Get the current back-filing terms Return the current back-filing terms shown before approving a BACK_FILING. This is global reference data, but a valid credential is still required. Returns 404 when no terms are published. Category: Filings Response fields: id (string, required) - Identifier of the current terms version. version (integer, required) - Monotonic version number of the terms. timeline (string, required) - Timeline copy shown to the customer. penaltiesAndInterest (string, required) - Penalties-and-interest copy shown to the customer. whatYouAreApproving (string, required) - Summary of what approving the terms commits to. fees (string, required) - Fees copy shown to the customer. helpArticleUrl (string) - Link to the help article, if any. helpArticleLabel (string, required) - Label for the help-article link. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Approve filings in bulk POST /filings/bulk/approve Source: https://docs.trykintsugi.com/reference/2026-10-06/approve-filings-in-bulk POST /filings/bulk/approve Approve filings in bulk Approve several filings in one organization. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization they belong to. Returns 200 with a per-filing `successful`/`failed` breakdown even when some filings cannot be approved (unknown id, not an approvable status, or a disabled jurisdiction). Approving BACK_FILING rows with published terms requires `backFilingTermsId`. Returns 403 PLAN_UPGRADE_REQUIRED when the organization is on a free plan, and 403 FORBIDDEN when the organization's plan does not include managed filings. Category: Filings Request body: filingIds (string[], required) - Ids of the filings to approve. Duplicates are ignored. backFilingTermsId (string) - Id of the back-filing terms version accepted for any BACK_FILING. backFilingTermsAcceptedAt (string) - When the customer accepted the back-filing terms (advisory). requestId (string) - Client-minted id for this confirm attempt, stored on the audit row. Response fields: successful (string[], required) - Filing ids acted on, or accepted for a worker when queued. failed (BulkFilingFailure[], required) - Requested filings that were not acted on, each with a reason. id (string, required) - Id of the filing that was not acted on. reason (string, required) - Why this filing was not acted on. queued (boolean) - Whether the batch was enqueued for a worker rather than applied inline. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Pause filings in bulk POST /filings/bulk/pause Source: https://docs.trykintsugi.com/reference/2026-10-06/pause-filings-in-bulk POST /filings/bulk/pause Pause filings in bulk Pause several filings in one organization. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization they belong to. `pauseIntent` says why (`review` needs `pausedUntilDate`). Returns 200 with a per-filing `successful`/`failed` breakdown even when some filings cannot be paused; large batches are enqueued and reported with `queued` true. Category: Filings Request body: filingIds (string[], required) - Ids of the filings to pause. Duplicates are ignored. pauseIntent (PublicPauseIntentEnum, required) - Why the filings are being paused. allowed values: review, assistance, skip pausedUntilDate (string) - Date a `review` pause auto-resumes, as YYYY-MM-DD, from today to the 15th of each filing's due month; a filing outside that range is reported in `failed`. Required for `review`; ignored for `assistance` and `skip`. pauseReason (string) - Optional text explaining why the filings are paused. A reason too long for the filing note is rejected with 400. requestId (string) - Client-minted id for this confirm attempt, stored on the audit row. Response fields: successful (string[], required) - Filing ids acted on, or accepted for a worker when queued. failed (BulkFilingFailure[], required) - Requested filings that were not acted on, each with a reason. id (string, required) - Id of the filing that was not acted on. reason (string, required) - Why this filing was not acted on. queued (boolean) - Whether the batch was enqueued for a worker rather than applied inline. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List filing jurisdictions GET /filings/jurisdictions Source: https://docs.trykintsugi.com/reference/2026-10-06/list-filing-jurisdictions GET /filings/jurisdictions List filing jurisdictions List the distinct jurisdictions your filings cover, for the list filter. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Returned as distinct state codes followed by the country codes of country-level filings. Category: Filings Response fields: jurisdictions (string[], required) - Distinct state codes, then the country codes of country-level filings, across every organization in scope. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Summarize filings GET /filings/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-filings GET /filings/summary Summarize filings Count filings by lifecycle status and total the scope's tax across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. A status with no filings is omitted rather than reported as zero. Category: Filings Response fields: total (integer, required) - Total filings in scope, across every status. statusCounts (FilingStatusCount[], required) - One entry per status present in scope. A status with no filings is omitted rather than reported as zero. status (PublicFilingStatusEnum, required) - The lifecycle status this count is for. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE count (integer, required) - Number of filings in scope with this status. totalTaxCollected (string, required) - Tax collected across open (UNFILED, FILING or SUBMITTED) filings in scope. totalTaxRemitted (string, required) - Tax remitted across FILED filings in scope. totalTaxCalculated (string, required) - Calculated tax across open (UNFILED, FILING or SUBMITTED) filings in scope. totalTaxLiability (string, required) - Total tax liability across open (UNFILED, FILING or SUBMITTED) filings in scope. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a filing by id GET /filings/{filing_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-filing-by-id GET /filings/{filing_id} Get a filing by id Fetch a single filing by id. Searched across every organization your credential owns, so no selector is needed for a known id. Pass `expand=salesBreakdown`, `expand=vatRecovery` and/or `expand=artifacts` to embed those buckets; omitted otherwise. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: expand (FilingExpand[]) - Buckets to embed on the filing. `salesBreakdown` embeds the period's sales composition; `vatRecovery` embeds the EU/UK input-VAT recovery rate pair; `artifacts` embeds the filing's return/payment/additional artifacts by slot. Omitted otherwise. allowed values: salesBreakdown, vatRecovery, artifacts Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE filingCategory (string, required) - The kind of filing period: REGULAR, AMENDMENT or BACK_FILING (a legacy PREPAYMENT value may appear on historical rows). taxType (PublicTaxTypeEnum, required) - Which taxes this filing covers, from the associated registration. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing jurisdiction, such as `US`, `CA` or `GB`. stateCode (string) - State or province code, or null for a country-level filing. stateName (string) - Human-readable state or province name, or null for a country-level filing. startDate (string, required) - First day of the filing period, as YYYY-MM-DD. endDate (string, required) - Last day of the filing period, as YYYY-MM-DD. dueDate (string) - When the return is due, as YYYY-MM-DD. dateFiled (string) - When the return was filed, as YYYY-MM-DD; null until filed. [truncated, see the reference page] --- # Approve a filing POST /filings/{filing_id}/approve Source: https://docs.trykintsugi.com/reference/2026-10-06/approve-a-filing POST /filings/{filing_id}/approve Approve a filing Approve a filing, moving it into the FILING lifecycle and locking its transactions. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. Approving a BACK_FILING with published terms requires `backFilingTermsId`. Pass `autoFile: true` to also turn on the organization's auto-file setting as part of the approval (applied only after it succeeds); omit it to leave the setting unchanged. Approving a filing that is not UNFILED or PAUSED is a no-op and returns the filing unchanged. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if its jurisdiction is not enabled, 403 PLAN_UPGRADE_REQUIRED when the organization is on a free plan, 403 FORBIDDEN when the organization's plan does not include managed filings, and 409 if a filing already exists for the period. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Request body: backFilingTermsId (string) - Id of the back-filing terms version the customer accepted, if any. backFilingTermsAcceptedAt (string) - When the customer accepted the back-filing terms (advisory). requestId (string) - Client-minted id for this confirm attempt, stored on the audit row so a double-submit or retry of one gesture can be collapsed by readers. autoFile (boolean) - When true, also turn on the organization's auto-file setting as part of the approval, so future returns file automatically. Applied only after the approval succeeds; omit, null or false leaves the setting unchanged. No effect for organizations on the new auto-filing experience. Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE [truncated, see the reference page] --- # Upload or replace a filing artifact PUT /filings/{filing_id}/artifacts/{artifact_type} Source: https://docs.trykintsugi.com/reference/2026-10-06/upload-or-replace-a-filing-artifact PUT /filings/{filing_id}/artifacts/{artifact_type} Upload or replace a filing artifact Store a filing's return or payment confirmation document, as `multipart/form-data` with the PDF in the `file` part. `artifactType` picks the slot: `RETURN` or `PAYMENT`. Uploading to a slot that already holds a document replaces it. Only a caller that files the organization's returns itself may upload: a partner with self-managed filings enabled (its portfolio key, or a partner user who can see the organization), or the organization's own ADMIN, OWNER or organization key when such a partner manages it. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization the filing belongs to. The filing's status does not change. Download the stored document through `GET /attachments/{id}/download`. The file must be a PDF of at most 10 MB. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if Kintsugi files the organization's returns or your credential is not its filer, 409 if the filing is not in the FILING, SUBMITTED or FILED status, 413 if the file is too large, and 422 if it is not a PDF. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. artifact_type (PublicFilingArtifactTypeEnum, required) - Which confirmation document the upload fills. allowed values: RETURN, PAYMENT Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 413, 422, 503 --- # List a filing's deferred transactions GET /filings/{filing_id}/deferredTransactions Source: https://docs.trykintsugi.com/reference/2026-10-06/list-a-filing-s-deferred-transactions GET /filings/{filing_id}/deferredTransactions List a filing's deferred transactions List the transactions deferred out of a filing period, keyset-paginated. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access. A filing type that does not support deferral returns an empty page. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (DeferredTransaction[], required) - The deferred transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. externalId (string) - Your stable identifier for the transaction. `null` when the source system supplied none. date (string) - Transaction date, as an RFC-3339 UTC timestamp. currency (string) - ISO-4217 currency of the amounts. totalAmount (string) - Total transaction amount. totalTaxLiabilityAmount (string) - Total tax liability for the transaction. status (PublicTransactionStatusEnum) - Lifecycle status of the transaction. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID transactionType (PublicTransactionTypeEnum) - Kind of transaction, e.g. SALE or FULL_CREDIT_NOTE. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION description (string) - Free-text description of the transaction, if any. nextCursor (string) - Opaque cursor for the next page. `null` on the last page. previousCursor (string) - Opaque cursor for the previous page. `null` on the first page. hasMore (boolean) - Whether a page exists after this one. hasPrevious (boolean) - Whether a page exists before this one. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a filing's enhanced data GET /filings/{filing_id}/enhanced-data Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-filing-s-enhanced-data GET /filings/{filing_id}/enhanced-data Get a filing's enhanced data Get a US filing's actual tax liability broken down by local jurisdiction. Returns `200` with the data when a current build is stored, and `200` with `FAILED` when the last build failed. Otherwise starts a build and returns `202` with `IN_PROGRESS`; poll until it is `DONE`. A filing with no transactions returns `DONE` with null data. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, and 400 when `jurisdiction` does not match the filing or the state has no enhanced data. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: jurisdiction (string, required) - Two-letter code of the filing's US state, such as `NY`. Must match the filing. Response fields: status (PublicEnhancedFilingDataStatusEnum, required) - `DONE`, `IN_PROGRESS`, or `FAILED`. allowed values: IN_PROGRESS, DONE, FAILED reportId (string) - Id of the stored build, to correlate polls and rebuilds. Null for a filing with no transactions, which has nothing to build. data (EnhancedFilingData) - The enhanced data. Null unless `status` is `DONE`, and null for a `DONE` filing with no transactions. filingId (string, required) - Id of the filing. stateCode (string, required) - Two-letter code of the filing's state. stateName (string, required) - Name of the filing's state. filingPeriod (EnhancedFilingDataPeriod, required) - The period the data covers. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. summary (object, required) - Liability totals for the period. jurisdictionBreakdown (object[], required) - Liability per local jurisdiction. jurisdictionBreakdownGroupedByCounty (object[]) - Liability per jurisdiction grouped by county, for states that report it. deductionsExemptions (object[], required) - Deductions and exemptions taken. transactionRefunds (object[], required) - Refunds that reduce the liability. additionalSummaryFields (object) - State-specific summary fields, if the state has any. additionalBreakdown (object, required) - State-specific breakdowns, keyed by name. useTax (object) - Use tax owed, for states that report it. Response statuses: 200, 202, 400, 401, 403, 404, 409, 422 --- # Rebuild a filing's enhanced data POST /filings/{filing_id}/enhanced-data/rebuild Source: https://docs.trykintsugi.com/reference/2026-10-06/rebuild-a-filing-s-enhanced-data POST /filings/{filing_id}/enhanced-data/rebuild Rebuild a filing's enhanced data Start a new enhanced-data build for a US filing, even when a current one is stored, and return `202` with `IN_PROGRESS`; poll `GET /filings/{filingId}/enhanced-data` until it is `DONE`. A build already in progress is reported instead of starting another. A filing with no transactions returns `200` with `DONE` and null data. Only the organization's own filer can rebuild, as for `PUT /filings/{filingId}/submission`: self-managed filings must be enabled, and a partner member must be assigned to the organization or the organization assigned to no member. Returns 403 otherwise. Allows 10 requests per minute for each portfolio, or for each organization when there is no portfolio; past that it returns `429`. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: jurisdiction (string, required) - Two-letter code of the filing's US state, such as `NY`. Must match the filing. Response fields: status (PublicEnhancedFilingDataStatusEnum, required) - `DONE`, `IN_PROGRESS`, or `FAILED`. allowed values: IN_PROGRESS, DONE, FAILED reportId (string) - Id of the stored build, to correlate polls and rebuilds. Null for a filing with no transactions, which has nothing to build. data (EnhancedFilingData) - The enhanced data. Null unless `status` is `DONE`, and null for a `DONE` filing with no transactions. filingId (string, required) - Id of the filing. stateCode (string, required) - Two-letter code of the filing's state. stateName (string, required) - Name of the filing's state. filingPeriod (EnhancedFilingDataPeriod, required) - The period the data covers. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. summary (object, required) - Liability totals for the period. jurisdictionBreakdown (object[], required) - Liability per local jurisdiction. jurisdictionBreakdownGroupedByCounty (object[]) - Liability per jurisdiction grouped by county, for states that report it. deductionsExemptions (object[], required) - Deductions and exemptions taken. transactionRefunds (object[], required) - Refunds that reduce the liability. additionalSummaryFields (object) - State-specific summary fields, if the state has any. [truncated, see the reference page] --- # Pause a filing POST /filings/{filing_id}/pause Source: https://docs.trykintsugi.com/reference/2026-10-06/pause-a-filing POST /filings/{filing_id}/pause Pause a filing Pause a filing. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. `pauseIntent` says why: `review` auto-resumes on `pausedUntilDate` (which is then required), `assistance` pauses indefinitely for manual help, and `skip` skips the period. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, and 400 if the filing cannot be paused in its current state or the request is invalid for the chosen intent. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Request body: pauseIntent (PublicPauseIntentEnum, required) - Why the filing is being paused. allowed values: review, assistance, skip pausedUntilDate (string) - Date a `review` pause auto-resumes, as YYYY-MM-DD, from today to the 15th of the month the filing is due. Required for `review`; ignored for `assistance` and `skip`. pauseReason (string) - Optional text explaining why the filing is paused. A reason too long for the filing note is rejected with 400. requestId (string) - Client-minted id for this confirm attempt, stored on the audit row so a double-submit or retry of one gesture can be collapsed by readers. Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE filingCategory (string, required) - The kind of filing period: REGULAR, AMENDMENT or BACK_FILING (a legacy PREPAYMENT value may appear on historical rows). taxType (PublicTaxTypeEnum, required) - Which taxes this filing covers, from the associated registration. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing jurisdiction, such as `US`, `CA` or `GB`. [truncated, see the reference page] --- # Recalculate a filing POST /filings/{filing_id}/recalculate Source: https://docs.trykintsugi.com/reference/2026-10-06/recalculate-a-filing POST /filings/{filing_id}/recalculate Recalculate a filing Queue a recalculation of a filing's amounts from its transactions. Only an administrator of a caller that files the organization's returns itself may recalculate: a partner with self-managed filings enabled (its portfolio key, or a partner ADMIN or OWNER), or the organization's own ADMIN, OWNER or organization key, or a reseller key for the portfolio that holds it, when such a partner manages it. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. Returns 202 with `status: QUEUED`; the recalculation runs in the background, so read the filing again for the new amounts. Only US and Canadian filings that are not in FILING, SUBMITTED or FILED status can be recalculated. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if Kintsugi files the organization's returns or your credential is not an administrator of its filer, and 400 if the filing cannot be recalculated. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Response fields: filingId (string, required) - Kintsugi's unique identifier for the filing. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing's jurisdiction. status (PublicFilingRecalculationStatusEnum, required) - `QUEUED` once the recalculation is queued. Poll `GET /filings/{filingId}` for the recalculated amounts. allowed values: QUEUED Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # Submit a filing's confirmation data PUT /filings/{filing_id}/submission Source: https://docs.trykintsugi.com/reference/2026-10-06/submit-a-filing-s-confirmation-data PUT /filings/{filing_id}/submission Submit a filing's confirmation data Save the confirmation data entered for a filing, or mark the filing as filed. Only the organization's own filer can submit, so self-managed filings must be enabled for the organization: a partner credential for its portfolio (a partner member must be assigned to the organization, or the organization must be assigned to no member), or the organization's admin, owner or organization API key. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization the filing belongs to. `action` is `save_draft` to store the data and leave the filing status unchanged, or `mark_filed` to store it and mark the filing filed. A field you omit is left unchanged and a field you send as `null` is cleared. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if the credential cannot submit for the organization or self-managed filings are not enabled, and 409 if the filing is not in FILING or SUBMITTED status. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Request body: action (PublicFilingSubmissionActionEnum, required) - Save the entered data as a draft, or mark the filing as filed. allowed values: save_draft, mark_filed paymentConfirmationId (string) - The confirmation id the jurisdiction issued for the payment. returnConfirmationId (string) - The confirmation id the jurisdiction issued for the return. amountAdjusted (string) - Manual adjustment to the amount due. amountFees (string) - Fees added to the amount due. amountPenalties (string) - Penalties added to the amount due. amountDiscounts (string) - Discounts applied to the amount due. Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE [truncated, see the reference page] --- # List imports GET /imports Source: https://docs.trykintsugi.com/reference/2026-10-06/list-imports GET /imports List imports List CSV imports across every organization your credential can access (narrow with a selector), newest first by `createdAt`, keyset-paginated. Archived imports are not listed. Filter with `source` (comma-separated, e.g. `SHOPIFY,STRIPE`). Category: Imports Query parameters: source (string) - Comma-separated import sources to filter by (e.g. SHOPIFY,STRIPE). limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Import[], required) - The results on this page. Empty when there are none. id (string, required) - Import id. organizationId (string, required) - Organization the import belongs to. source (string, required) - Import source (a connector name, or IMPORT for a manual CSV upload). importType (PublicImportTypeEnum, required) - TRANSACTIONS for a sales/purchase CSV, PRODUCT_UPDATES for a product bulk-update workbook. allowed values: TRANSACTIONS, PRODUCT_UPDATES direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file. null when set per row instead (rows default to SALE). allowed values: SALE, PURCHASE fileName (string) - Original uploaded file name. null until known. status (PublicImportStatusEnum, required) - Import processing status. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) rowCount (integer) - Total rows in the uploaded file. null until counted. importedCount (integer) - Rows successfully imported as transactions. skippedCount (integer) - Rows skipped during import. createdAt (string, required) - When the import was created. updatedAt (string) - When the import row last changed. submittedAt (string) - When submit-stage processing started. null until submitted. validationCompletedAt (string) - When validation finished. null until it completes. validationTruncated (boolean) - True when the validation error log was truncated (only the first errors were kept). validRowCount (integer) - Rows that passed validation. null until validation completes. invalidRowCount (integer) - Rows that failed validation. null until validation completes. [truncated, see the reference page] --- # Create an import and get a single-file upload URL POST /imports/initiate Source: https://docs.trykintsugi.com/reference/2026-10-06/create-an-import-and-get-a-single-file-upload-url POST /imports/initiate Create an import and get a single-file upload URL Create an import row for one file and return a presigned URL to PUT its bytes to; check `uploadMode` for how to deliver the file. Set `importType` to `PRODUCT_UPDATES` for a product bulk-update .xlsx workbook. Requires file upload v2 for the target organization. `userId` is required and non-empty with an API key and ignored for signed-in sessions, which record the authenticated user. Category: Imports Request body: fileName (string, required) - Original file name of the upload. size (integer, required) - Declared file size in bytes. contentType (string) - MIME type of the file to upload. source (string, required) - Import source (a connector name, or IMPORT for a manual upload). userId (string) - Required and non-empty when authenticating with an API key: the id of the person or process performing the upload, recorded for audit. Ignored for signed-in sessions, which record the authenticated user. direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file; blank per-row direction cells take this value. allowed values: SALE, PURCHASE importType (PublicImportTypeEnum) - TRANSACTIONS (default) for a sales/purchase CSV. PRODUCT_UPDATES for a product bulk-update workbook: fileName must end in .xlsx and contentType must be the Excel workbook MIME type. allowed values: TRANSACTIONS, PRODUCT_UPDATES Response fields: importId (string, required) - Id of the created import. uploadUrl (string, required) - URL to PUT the file bytes to; a path on this API when uploadMode is local_internal. expiresAt (string, required) - When uploadUrl expires. uploadMode (string, required) - How to deliver the file. `presigned` sends it to the returned URL directly. `local_internal` only appears in local development: send it to the returned path on this API with your credential. allowed values: presigned, local_internal Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Count imports GET /imports/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/count-imports GET /imports/summary Count imports Count imports across every organization your credential can access (portfolio-wide, narrowed with a selector). Archived imports are counted, so `total` can exceed the number of imports `GET /imports` lists. Category: Imports Response fields: total (integer, required) - Total imports in scope, archived imports included. Larger than the number of items `GET /imports` lists when any import is archived. Response statuses: 200, 400, 401, 403, 404, 422 --- # Download a CSV import template GET /imports/template Source: https://docs.trykintsugi.com/reference/2026-10-06/download-a-csv-import-template GET /imports/template Download a CSV import template Download the standard import template with the source column pre-filled. Requires file upload v2 for the target organization. Category: Imports Query parameters: source (string) - Source value to embed in the template (e.g. STRIPE, PROVISION). All sources use the same standard CSV template format. provisionTemplate (string) - For PROVISION only: cash or accrual. format (string) - Download format: csv (default) or xlsx. xlsx is ProVision-only. direction (string) - SALE (default) or PURCHASE. Response statuses: 200, 400, 401, 403, 404, 422 --- # Create upload targets for one or more CSV files POST /imports/upload-urls Source: https://docs.trykintsugi.com/reference/2026-10-06/create-upload-targets-for-one-or-more-csv-files POST /imports/upload-urls Create upload targets for one or more CSV files Create an import row per file and return a presigned S3 POST target for each. Check `uploadMode` for how to deliver the file. Prefer `POST /imports/initiate` for a single file. `userId` is required and non-empty with an API key and ignored for signed-in sessions, which record the authenticated user. Category: Imports Request body: files (ImportUploadFile[], required) - Files to create upload targets for. fileName (string, required) - Name of the file to upload. source (string, required) - Import source the files belong to. userId (string) - Required and non-empty when authenticating with an API key: the id of the person or process performing the upload, recorded for audit. Ignored for signed-in sessions, which record the authenticated user. direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file; blank per-row direction cells take this value. allowed values: SALE, PURCHASE Response fields: fileName (string, required) - Name of the file this target is for. importId (string, required) - Id of the import row created for this file. uploadUrl (string, required) - Where to upload the file: a presigned S3 POST URL, or a path on this API when uploadMode is local_internal. uploadFields (object) - Additional form fields required on the upload POST. uploadMode (string, required) - How to deliver the file. `presigned` sends it to the returned URL directly. `local_internal` only appears in local development: send it to the returned path on this API with your credential. allowed values: presigned, local_internal Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Validate a CSV file POST /imports/validate Source: https://docs.trykintsugi.com/reference/2026-10-06/validate-a-csv-file POST /imports/validate Validate a CSV file Check a CSV file's contents before uploading it. Always answers 200; check `isValid` and `errors` to see whether the file passed. Category: Imports Request body: fileName (string, required) - Name of the file being validated. data (string, required) - Raw CSV file contents. source (string, required) - Import source the file was exported for. direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file; blank per-row direction cells take this value. allowed values: SALE, PURCHASE Response fields: isValid (boolean, required) - True when every row passed validation. fileName (string, required) - Name of the file that was validated. rowCount (integer, required) - Number of data rows found in the file. errors (string[]) - Human-readable validation error messages. Empty when isValid is true. resultData (ImportPreviewRow[]) - Rows that passed validation, parsed and normalized. Empty when the file was rejected outright or every row failed. relatedExternalId (string) - Id of a related transaction, for a credit note row. transactionExternalId (string, required) - Id of the transaction in the source system. status (PublicTransactionStatusEnum, required) - Transaction status in the source system. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID transactionSource (string) - Source of the transaction (a connector name, or IMPORT for a manual CSV upload). date (string, required) - Date the transaction took place. currency (PublicCurrencyEnum, required) - Currency of the transaction. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) description (string) - Description of the transaction. customerId (string, required) - Id of the customer in the source system. taxId (string) - Tax registration number of the customer. customerName (string) - Full name of the customer. customerEmail (string) - Email address of the customer. customerCompanyName (string) - Registered or legal business name of the customer. marketplace (boolean) - True when the transaction was facilitated by a marketplace. shipToPhone (string) - Phone number of the ship-to address. shipToStreetLine1 (string) - First line of the ship-to address. [truncated, see the reference page] --- # Get an import by id GET /imports/{import_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-an-import-by-id GET /imports/{import_id} Get an import by id Fetch a single import by id. Returns 404 if it does not exist or belongs to an organization your credential cannot access. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: id (string, required) - Import id. organizationId (string, required) - Organization the import belongs to. source (string, required) - Import source (a connector name, or IMPORT for a manual CSV upload). importType (PublicImportTypeEnum, required) - TRANSACTIONS for a sales/purchase CSV, PRODUCT_UPDATES for a product bulk-update workbook. allowed values: TRANSACTIONS, PRODUCT_UPDATES direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file. null when set per row instead (rows default to SALE). allowed values: SALE, PURCHASE fileName (string) - Original uploaded file name. null until known. status (PublicImportStatusEnum, required) - Import processing status. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) rowCount (integer) - Total rows in the uploaded file. null until counted. importedCount (integer) - Rows successfully imported as transactions. skippedCount (integer) - Rows skipped during import. createdAt (string, required) - When the import was created. updatedAt (string) - When the import row last changed. submittedAt (string) - When submit-stage processing started. null until submitted. validationCompletedAt (string) - When validation finished. null until it completes. validationTruncated (boolean) - True when the validation error log was truncated (only the first errors were kept). validRowCount (integer) - Rows that passed validation. null until validation completes. invalidRowCount (integer) - Rows that failed validation. null until validation completes. ingestCompletedAt (string) - When row processing finished. null until it completes. processedRowCount (integer) - Rows processed so far. null when rows are not currently being processed. ingestedRowCount (integer) - Rows imported so far. null when rows are not currently being processed. failedRowCount (integer) - Rows that failed to import so far. null when rows are not currently being processed. [truncated, see the reference page] --- # Get a download link for an import's error artifact GET /imports/{import_id}/error-file Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-download-link-for-an-import-s-error-artifact GET /imports/{import_id}/error-file Get a download link for an import's error artifact Return download instructions for the validation or import error artifact. Pass `phase=import` for row-processing errors; validation errors are the default. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Query parameters: phase (string) - 'validation' (default) or 'import'. Response fields: downloadUrl (string, required) - Presigned URL to download the error artifact. Empty when the bytes are returned inline instead. expiresInSeconds (integer, required) - How long downloadUrl stays valid, in seconds. 0 when downloadUrl is empty. inlineContentBase64 (string) - Base64-encoded error artifact bytes, present only when downloadUrl is empty. Response statuses: 200, 400, 401, 403, 404, 422 --- # Import the validated rows POST /imports/{import_id}/ingest Source: https://docs.trykintsugi.com/reference/2026-10-06/import-the-validated-rows POST /imports/{import_id}/ingest Import the validated rows Import the rows that passed validation. `submitMode` `ALL` requires every row to have passed validation; `VALID_ONLY` imports the rows that passed and skips the rest. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Request body: submitMode (string, required) - ALL requires every row to have passed validation. VALID_ONLY imports the rows that passed and skips the rest. allowed values: ALL, VALID_ONLY idempotencyKey (string, required) - Caller-supplied key so a retried import request does not queue twice. Response fields: importId (string, required) - Id of the import. status (PublicImportStatusEnum, required) - Import processing status after the request. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) Response statuses: 202, 400, 401, 403, 404, 409, 422, 503 --- # Start processing an uploaded import POST /imports/{import_id}/submit Source: https://docs.trykintsugi.com/reference/2026-10-06/start-processing-an-uploaded-import POST /imports/{import_id}/submit Start processing an uploaded import Start submit-stage processing (a malware scan, then validation) for an import created via `initiate`. Answers 202 once queued; an import that already advanced past submit answers 200 with its current status. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: importId (string, required) - Id of the import. status (PublicImportStatusEnum, required) - Current import processing status. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) detail (string, required) - Why submit was a no-op: the import already advanced past the submit stage. Response statuses: 200, 202, 400, 401, 403, 404, 409, 422, 503 --- # List marketplaces GET /marketplaces Source: https://docs.trykintsugi.com/reference/2026-10-06/list-marketplaces GET /marketplaces List marketplaces List marketplace-facilitator registry rows, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `status` defaults to `NO` and `NEEDS_REVIEW` rows; set `includeConfirmed` to see `YES` rows instead. Filter with `sourceTypes` (comma-separated), `sourceNames` (comma-separated), `sourceId` and `connectionId`. Pass `limit` and the opaque `cursor` from a prior response to page. Category: Marketplaces Query parameters: sourceTypes (string) - Comma-separated integration sources; matches any of them. sourceNames (string) - Comma-separated secondary source names to match. sourceId (string) - Substring match on the secondary source id. connectionId (string) - Limit results to marketplaces on this connection. includeConfirmed (boolean) - When true, return `YES` rows instead of `NO` / `NEEDS_REVIEW`. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Marketplace[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for this marketplace registry row. organizationId (string, required) - Organization this marketplace registry belongs to. clientName (string) - Display name of the organization this marketplace belongs to, or `null` when the organization has no name set. connectionId (string) - Connection this marketplace channel is synced through, or `null` when it is not tied to one. sourceId (string) - Secondary source id the connector reported for this channel, or `null` when it reported none. sourceName (string) - Secondary source name the connector reported for this channel (e.g. Amazon, eBay), or `null` when it reported none. sourceType (string) - Integration source that synced this registry row, or `null` when it is not tied to one. status (PublicMarketplaceStatusEnum, required) - Confirmation state: whether transactions matched to this row are treated as marketplace-facilitated sales. allowed values: YES, NO, NEEDS_REVIEW processingStatus (PublicMarketplaceProcessingStatusEnum, required) - Progress of the last change to `status`. allowed values: IDLE, PROCESSING, COMPLETED, FAILED [truncated, see the reference page] --- # Get a marketplace by id GET /marketplaces/{marketplace_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-marketplace-by-id GET /marketplaces/{marketplace_id} Get a marketplace by id Fetch a single marketplace-facilitator registry row by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Response fields: id (string, required) - Kintsugi's unique identifier for this marketplace registry row. organizationId (string, required) - Organization this marketplace registry belongs to. clientName (string) - Display name of the organization this marketplace belongs to, or `null` when the organization has no name set. connectionId (string) - Connection this marketplace channel is synced through, or `null` when it is not tied to one. sourceId (string) - Secondary source id the connector reported for this channel, or `null` when it reported none. sourceName (string) - Secondary source name the connector reported for this channel (e.g. Amazon, eBay), or `null` when it reported none. sourceType (string) - Integration source that synced this registry row, or `null` when it is not tied to one. status (PublicMarketplaceStatusEnum, required) - Confirmation state: whether transactions matched to this row are treated as marketplace-facilitated sales. allowed values: YES, NO, NEEDS_REVIEW processingStatus (PublicMarketplaceProcessingStatusEnum, required) - Progress of the last change to `status`. allowed values: IDLE, PROCESSING, COMPLETED, FAILED transactions (integer, required) - Count of transactions currently matched to this registry row. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update a marketplace's confirmation status PATCH /marketplaces/{marketplace_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-marketplace-s-confirmation-status PATCH /marketplaces/{marketplace_id} Update a marketplace's confirmation status Set a marketplace's confirmation `status`. The update is processed asynchronously: every transaction currently matched to this marketplace is queued to be re-evaluated, and `processingStatus` on the response tracks that job. Returns 409 if a previous change to this marketplace is still processing. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Request body: status (PublicMarketplaceStatusEnum, required) - New confirmation state to set. allowed values: YES, NO, NEEDS_REVIEW requestId (string) - Optional client-generated id for this confirm attempt (a UUID or a short slug), stored on the audit trail so a later read can tell repeated confirms apart. Response fields: id (string, required) - Kintsugi's unique identifier for this marketplace registry row. organizationId (string, required) - Organization this marketplace registry belongs to. clientName (string) - Display name of the organization this marketplace belongs to, or `null` when the organization has no name set. connectionId (string) - Connection this marketplace channel is synced through, or `null` when it is not tied to one. sourceId (string) - Secondary source id the connector reported for this channel, or `null` when it reported none. sourceName (string) - Secondary source name the connector reported for this channel (e.g. Amazon, eBay), or `null` when it reported none. sourceType (string) - Integration source that synced this registry row, or `null` when it is not tied to one. status (PublicMarketplaceStatusEnum, required) - Confirmation state: whether transactions matched to this row are treated as marketplace-facilitated sales. allowed values: YES, NO, NEEDS_REVIEW processingStatus (PublicMarketplaceProcessingStatusEnum, required) - Progress of the last change to `status`. allowed values: IDLE, PROCESSING, COMPLETED, FAILED transactions (integer, required) - Count of transactions currently matched to this registry row. Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # List transactions matched to a marketplace GET /marketplaces/{marketplace_id}/transactions Source: https://docs.trykintsugi.com/reference/2026-10-06/list-transactions-matched-to-a-marketplace GET /marketplaces/{marketplace_id}/transactions List transactions matched to a marketplace List transactions matched to one marketplace, keyset-paginated. Searched across every organization your credential owns, so no selector is needed. Includes transactions with no customer. Newest first unless `orderBy`/`order` say otherwise. Page with `limit` and `cursor`. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Query parameters: orderBy (PublicMarketplaceTransactionSortEnum) - Field to sort by. Omit both `orderBy` and `order` for newest first (`date` descending). Missing values sort last in both directions. allowed values: date, customerName, state, status order (PublicMarketplaceSortOrderEnum) - Sort direction. Defaults to `asc` when `orderBy` or `order` is set alone; `orderBy` defaults to `date`. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (MarketplaceTransaction[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. connectionId (string) - Connection the transaction was synced through. customerId (string) - Kintsugi customer this transaction is attributed to, or `null` when it has none. customerName (string) - Display name of `customerId`, or `null` when it has none. description (string) - Description reported by the source, if any. date (string) - When the transaction occurred. state (string) - Jurisdiction (state/province) code the source reported for this transaction, or `null` when it reported none. amount (string) - Transaction total, before conversion, or `null` when the source reported none. `null` is not zero. convertedAmount (string) - `amount` in the organization's home currency, or `null` when no conversion applied. currency (PublicCurrencyEnum) - ISO-4217 currency `convertedAmount` is expressed in, or `null` when no conversion applied. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) status (PublicTransactionStatusEnum, required) - Settlement state. [truncated, see the reference page] --- # Mark every matched transaction as a marketplace sale POST /marketplaces/{marketplace_id}/transactions/mark-as-marketplace Source: https://docs.trykintsugi.com/reference/2026-10-06/mark-every-matched-transaction-as-a-marketplace-sale POST /marketplaces/{marketplace_id}/transactions/mark-as-marketplace Mark every matched transaction as a marketplace sale Queue every transaction currently matched to this marketplace to be marked as a marketplace-facilitated sale. This runs the same reclassification `status=YES` queues, without changing `status` itself -- use this to re-apply it after new transactions synced. Small batches are applied inline (`queued: false`); larger ones are queued to SQS (`queued: true`) and `status` is unaffected either way. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Response fields: marketplaceId (string, required) - The marketplace this action was run for. queued (boolean, required) - Whether the work was queued to run asynchronously (`true`) or completed before this response returned (`false`, small batches only). Response statuses: 202, 400, 401, 403, 404, 422 --- # List nexus determinations GET /nexus Source: https://docs.trykintsugi.com/reference/2026-10-06/list-nexus-determinations GET /nexus List nexus determinations Returns a keyset page of nexus determinations for organizations your credential owns. Send `Organization-Id`, `Connection-Id`, or `Entity-Id` to narrow to one organization. A cursor is valid only for the filters and organization scope that issued it. Period history is omitted; get a nexus by ID for typed periods. Category: Nexus Query parameters: status (string) - Comma-separated lifecycle statuses. Matches any listed value. countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes. Matches any listed value. stateCode (string) - Comma-separated state or province codes. Matches any listed value. taxType (string) - Comma-separated tax types. Matches any listed value. disregarded (PublicDisregardedFilterEnum) - Which disregard state to return. `CURRENT` returns rows where `isCurrentlyDisregarded` is true; `NONE` returns rows where it is false; `EVER` returns every row that carries a `disregardedAt`, including ones later activity re-exposed. Omit for no disregard filter. allowed values: NONE, CURRENT, EVER collectedTaxNexusMet (boolean) - Filter on whether nexus was met by collecting tax in the jurisdiction. Passing `true` also lifts the default collected-tax-only exclusion, so `collectedTaxOnly` is unnecessary alongside it. collectedTaxOnly (boolean) - Include exposed rows whose only nexus is collected tax. These are hidden by default because collecting tax is not itself an economic or physical exposure. excludeEuEconomicOnly (boolean) - Drop EU member-state rows whose only nexus is economic. Those obligations are represented by the `ZZ_EU` aggregator row, so listing both counts one obligation twice. search (string) - Case-insensitive match on state code or state name. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (NexusSummary[], required) - Nexus rows on this page. id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. [truncated, see the reference page] --- # Export nexus report POST /nexus/reports/export Source: https://docs.trykintsugi.com/reference/2026-10-06/export-nexus-report POST /nexus/reports/export Export nexus report Queue a nexus export for one organization. The report is generated asynchronously and a download link is emailed, so the response is a 202 rather than the file itself. An API-key credential must provide `email`; a first-party bearer session may omit it to send the report to its own account email. Returns 400 if the organization has disabled email delivery. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Nexus Request body: email (string) - Address the generated report download link is emailed to. Required for an API-key credential (it has no session user). For a first-party bearer session it is optional: omit it to send the report to your own account email. Response fields: organizationId (string, required) - Organization the export was queued for. email (string, required) - Address the report download link will be emailed to. Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # Get a nexus determination GET /nexus/{nexus_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-nexus-determination GET /nexus/{nexus_id} Get a nexus determination Returns one nexus determination, including typed period history. Searches every organization your credential owns. Returns 404 if the nexus does not exist or is not visible to your credential. Category: Nexus Path parameters: nexus_id (string, required) Response fields: id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. stateName (string, required) - Display name of the state or province. status (PublicNexusStatusEnum, required) - Lifecycle state of this nexus determination. Ignore unrecognized values. allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED nexusType (PublicNexusTypeEnum, required) - Kind of jurisdiction. `CANADA_FEDERAL` is the wire value for every federal jurisdiction, not only Canada. Ignore unrecognized values. allowed values: CANADA_FEDERAL, EU_AGGREGATOR, EU_IOSS, STATE, EU_MEMBER_STATE taxType (PublicNexusTaxTypeEnum, required) - Tax obligation this row tracks. Sales and use are separate rows. Ignore unrecognized values. allowed values: SALES_TAX, USE_TAX, RETAIL_DELIVERY_FEE salesOrTransactions (PublicSalesOrTransactionsEnum, required) - Volume the jurisdiction counts toward its threshold. Ignore unrecognized values. allowed values: EITHER, SALES, BOTH, TRANSACTIONS periodModel (PublicPeriodModelEnum, required) - How the jurisdiction measures the economic-nexus lookback window. Ignore unrecognized values. allowed values: CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, PRECEDING_YEAR_FROM_OCTOBER, CALENDAR_YEAR, PREVIOUS_12_MONTHS, CURRENT_OR_PREVIOUS_12_MONTHS, PREVIOUS_4_QUARTERS, PREVIOUS_4_QUARTERS_OFFSET, PRECEDING_YEAR, PRECEDING_YEAR_QUARTERLY, PRECEDING_YEAR_QUARTERLY_OFFSET currency (string, required) - ISO-4217 currency of the amount fields on this row. [truncated, see the reference page] --- # Disregard a nexus POST /nexus/{nexus_id}/disregard Source: https://docs.trykintsugi.com/reference/2026-10-06/disregard-a-nexus POST /nexus/{nexus_id}/disregard Disregard a nexus Disregard an exposed nexus, moving it off the exposed list. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. The body is optional: omit it to disregard for the ordinary reason, or send `disregardedType` to record an Importer of Record opt-out instead. Returns 404 if the nexus does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Returns 400 if the nexus is not exposed, is already disregarded, or is not eligible for the opt-out you asked for. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Request body: disregardedType (PublicDisregardWriteTypeEnum) - Why the nexus is being disregarded. `DISREGARDED` is a manual disregard. `IOR_OPT_OUT` records that the organization declines to act as Importer of Record for the jurisdiction, and is accepted only when the nexus is `iorOptOutEligible`. Defaults to `DISREGARDED`. allowed values: DISREGARDED, IOR_OPT_OUT requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. stateName (string, required) - Display name of the state or province. status (PublicNexusStatusEnum, required) - Lifecycle state of this nexus determination. Ignore unrecognized values. allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED nexusType (PublicNexusTypeEnum, required) - Kind of jurisdiction. `CANADA_FEDERAL` is the wire value for every federal jurisdiction, not only Canada. Ignore unrecognized values. allowed values: CANADA_FEDERAL, EU_AGGREGATOR, EU_IOSS, STATE, EU_MEMBER_STATE [truncated, see the reference page] --- # List a nexus's exposure history GET /nexus/{nexus_id}/exposure-history Source: https://docs.trykintsugi.com/reference/2026-10-06/list-a-nexus-s-exposure-history GET /nexus/{nexus_id}/exposure-history List a nexus's exposure history List the recorded exposure changes for a nexus, such as its collected tax reaching zero. Searches every organization your credential owns, so no selector is needed for a known id. Returns 404 if the nexus does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. A nexus with no recorded changes returns an empty list. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Response fields: id (string, required) - Opaque unique identifier for this event. stateCode (string, required) - State or province code the event was recorded for. eventType (PublicNexusExposureEventTypeEnum, required) - What kind of exposure change this event records. Ignore unrecognized values. allowed values: NET_COLLECTED_TAX_ZEROED_OUT reason (string, required) - Human-readable explanation of why the event was recorded. netTax (string, required) - Net collected tax at the time of the event, as a decimal string. This is `totalCollected` minus `totalRefunded`. totalCollected (string, required) - Total tax collected at the time of the event, as a decimal string. totalRefunded (string, required) - Total tax refunded at the time of the event, as a decimal string. timestamp (string, required) - When the exposure change the event records took effect, as an RFC-3339 UTC timestamp. createdAt (string, required) - When this event row was written, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Resolve a nexus's collected-tax exposure POST /nexus/{nexus_id}/resolve-collected-transactions Source: https://docs.trykintsugi.com/reference/2026-10-06/resolve-a-nexus-s-collected-tax-exposure POST /nexus/{nexus_id}/resolve-collected-transactions Resolve a nexus's collected-tax exposure Clear the collected-tax exposure on a nexus and schedule a recalculation. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. The request body is optional; omit it, or send an empty object, for the default resolve. When present, `requestId` identifies this confirm attempt so duplicate submits of the same gesture can be grouped. Returns 404 if the nexus does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Returns 400 if your credential has no user identity to attribute the resolve to. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Request body: requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. stateName (string, required) - Display name of the state or province. status (PublicNexusStatusEnum, required) - Lifecycle state of this nexus determination. Ignore unrecognized values. allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED nexusType (PublicNexusTypeEnum, required) - Kind of jurisdiction. `CANADA_FEDERAL` is the wire value for every federal jurisdiction, not only Canada. Ignore unrecognized values. allowed values: CANADA_FEDERAL, EU_AGGREGATOR, EU_IOSS, STATE, EU_MEMBER_STATE taxType (PublicNexusTaxTypeEnum, required) - Tax obligation this row tracks. Sales and use are separate rows. Ignore unrecognized values. allowed values: SALES_TAX, USE_TAX, RETAIL_DELIVERY_FEE [truncated, see the reference page] --- # Onboarding step completion status GET /onboarding/steps-status Source: https://docs.trykintsugi.com/reference/2026-10-06/onboarding-step-completion-status GET /onboarding/steps-status Onboarding step completion status Which onboarding steps are complete for the organization selected by Organization-Id, Connection-Id, or Entity-Id. Category: Experience Response fields: transactionsStatus (boolean, required) - Whether the org has imported or connected transaction data. physicalNexusStatus (boolean, required) - Whether physical nexus locations are recorded. organizationDetailsStatus (boolean, required) - Whether required organization profile fields are complete. bankDetailsStatus (boolean, required) - Whether payout or remittance bank details are on file. primaryProductsStatus (boolean, required) - Whether primary product categories are configured. planStepStatus (boolean, required) - Whether a billing plan step is complete. onboardingStepsStatus (boolean, required) - Whether all required onboarding steps are complete. autoRegister (boolean, required) - Whether automatic registration is enabled, if configured. autoFile (boolean, required) - Whether automatic filing is enabled, if configured. physicalMailAddressStatus (string, required) - Status of the physical mailing address step, if applicable. accountSetupComplete (boolean) - Sticky flag when account setup gating is satisfied. checklistBranch (string) - Onboarding checklist branch identifier for triage UI. setupPaymentStatus (boolean) - Whether payment setup is complete. mailStepStatus (boolean) - Whether the mail-related onboarding step is complete. ecmStepStatus (boolean) - Whether the exemption certificate management step is complete. analyticsStepStatus (boolean) - Whether the analytics onboarding step is complete. Response statuses: 200, 400, 401, 404, 422 --- # Get organization details GET /organization-details Source: https://docs.trykintsugi.com/reference/2026-10-06/get-organization-details GET /organization-details Get organization details Returns the organization details for the org selected by Organization-Id, Connection-Id, or Entity-Id. Owners and contact SSN/DL are not included. Category: Organizations Response fields: businessDetails (OrganizationDetailsBusinessDetails, required) - Identity and non-address business information. businessName (string) - Legal business name, or null when unset. entityType (PublicEntityTypeEnum) - Legal entity type, or null when unset. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) dba (string) - Doing-business-as name, or null when unset. incorporationState (string) - State or province of incorporation, or null when unset. incorporationCountry (string) - ISO 3166-1 alpha-2 country of incorporation, or null when unset. ein (string) - Employer identification number, or null when unset. businessDescription (string) - Short description of the business, or null when unset. homeStateRegistration (string) - Home-state registration identifier, or null when unset. naics (string) - NAICS industry code, or null when unset. firstOperationsDate (string) - Date the business began operations (YYYY-MM-DD), or null when unset. businessPhone (string) - Primary business phone, or null when unset. businessEmail (string) - Primary business email, or null when unset. businessFiscalYearEnd (string) - Fiscal year end date (YYYY-MM-DD), or null when unset. accountingModel (PublicAccountingModelEnum) - Accounting basis, or null when unset. allowed values: ACCRUAL, CASH addresses (OrganizationDetailsAddresses, required) - Company, business, and mailing addresses. company (OrganizationDetailsCompanyAddress, required) - Legal / company address. address1 (string) - First address line, or null when unset. address2 (string) - Second address line, or null when unset. city (string) - City, or null when unset. state (string) - State or province code, or null when unset. postalCode (string) - Postal or ZIP code, or null when unset. [truncated, see the reference page] --- # Update organization details PATCH /organization-details Source: https://docs.trykintsugi.com/reference/2026-10-06/update-organization-details PATCH /organization-details Update organization details Sectioned upsert of business details, addresses, and contact. Any subset of sections may be sent; absent sections are unchanged. A section that IS present replaces that section as a whole, so send every field you want to keep: the patch granularity is the section, not the field. Creates the details row when missing. Contact SSN/DL and auto-file flags are not accepted. Category: Organizations Request body: businessDetails (BusinessDetailsUpdate) - Identity and non-address business fields. Absent means no change. businessName (string, required) - Legal business name. entityType (PublicEntityTypeEnum, required) - Legal entity type. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) dba (string, required) - Doing-business-as name. incorporationState (string, required) - State or province of incorporation. incorporationCountry (string, required) - ISO 3166-1 alpha-2 country of incorporation. ein (string, required) - Employer identification number. businessDescription (string, required) - Short description of the business. firstOperationsDate (string, required) - Date the business began operations (YYYY-MM-DD). taxId (string) - Incorporation tax id to upsert, or null to leave unchanged. homeStateRegistration (string) - Home-state registration identifier. Omit or send null to leave unchanged; this API does not clear it. naics (string) - NAICS industry code. Omit or send null to leave unchanged; this API does not clear it. businessPhone (string) - Primary business phone. Omit or send null to leave unchanged; this API does not clear it. businessEmail (string) - Primary business email. Omit or send null to leave unchanged; this API does not clear it. businessFiscalYearEnd (string) - Fiscal year end date (YYYY-MM-DD). Omit or send null to leave unchanged; this API does not clear it. accountingModel (PublicAccountingModelEnum) - Accounting basis. Omit or send null to leave unchanged; this API does not clear it. allowed values: ACCRUAL, CASH [truncated, see the reference page] --- # Get organization settings GET /organization-settings Source: https://docs.trykintsugi.com/reference/2026-10-06/get-organization-settings GET /organization-settings Get organization settings Returns the organization settings for the org selected by Organization-Id, Connection-Id, or Entity-Id. Category: Organization Settings Response fields: enableEuRegistration (boolean, required) - Whether EU / OSS registration is enabled for the organization. preferCollectedTaxAmounts (boolean, required) - Whether filings prefer tax amounts collected at the source over Kintsugi-calculated amounts. useSourceProductTaxExempt (boolean, required) - Whether sync respects the source system's product tax-exempt flag instead of Kintsugi classification. allowProductUpdates (boolean, required) - Whether integration-driven product updates are applied. allowAddressUpdates (boolean, required) - Whether integration-driven transaction address updates are applied. enableBusinessAddressFallback (boolean, required) - Whether the business address is used as a fallback when a transaction has no ship-to or bill-to address. autoFile (boolean, required) - Whether eligible filings are submitted automatically. autoRegister (boolean, required) - Whether registrations are opened automatically when nexus is reached. Response statuses: 200, 400, 401, 404, 422 --- # Update organization settings PATCH /organization-settings Source: https://docs.trykintsugi.com/reference/2026-10-06/update-organization-settings PATCH /organization-settings Update organization settings Updates the writable settings. Any subset of fields may be sent; absent fields are unchanged. autoFile / autoRegister require existing organization details. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to change its settings. Category: Organization Settings Request body: enableEuRegistration (boolean) - Whether EU / OSS registration is enabled. Absent means no change. preferCollectedTaxAmounts (boolean) - Whether filings prefer collected tax amounts. Absent means no change. useSourceProductTaxExempt (boolean) - Whether sync respects the source product tax-exempt flag. Absent means no change. allowProductUpdates (boolean) - Whether integration-driven product updates are applied. Absent means no change. allowAddressUpdates (boolean) - Whether integration-driven address updates are applied. Absent means no change. enableBusinessAddressFallback (boolean) - Whether the business address is used as an address fallback. Absent means no change. autoFile (boolean) - Whether eligible filings are submitted automatically. Absent means no change. autoRegister (boolean) - Whether registrations are opened automatically. Absent means no change. requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: enableEuRegistration (boolean, required) - Whether EU / OSS registration is enabled for the organization. preferCollectedTaxAmounts (boolean, required) - Whether filings prefer tax amounts collected at the source over Kintsugi-calculated amounts. useSourceProductTaxExempt (boolean, required) - Whether sync respects the source system's product tax-exempt flag instead of Kintsugi classification. allowProductUpdates (boolean, required) - Whether integration-driven product updates are applied. allowAddressUpdates (boolean, required) - Whether integration-driven transaction address updates are applied. enableBusinessAddressFallback (boolean, required) - Whether the business address is used as a fallback when a transaction has no ship-to or bill-to address. autoFile (boolean, required) - Whether eligible filings are submitted automatically. autoRegister (boolean, required) - Whether registrations are opened automatically when nexus is reached. [truncated, see the reference page] --- # Get exemption-reminder settings GET /organization-settings/exemption-reminders Source: https://docs.trykintsugi.com/reference/2026-10-06/get-exemption-reminder-settings GET /organization-settings/exemption-reminders Get exemption-reminder settings Returns the ECM exemption-reminder settings for the selected organization. Category: Organization Settings Response fields: expiringRemindersEnabled (boolean, required) - Master toggle for expiring-exemption reminders. expiringReminderChips (integer[], required) - Days before expiry to send expiring-exemption reminders. expiringEnabledAt (string) - Server-managed watermark stamped the first time expiring reminders are turned on; null means they never have been. It is not cleared when reminders are turned off, so a non-null value does not mean they are on now — read `expiringRemindersEnabled` for the current state. postExpiryReminderEnabled (boolean, required) - Whether the one-shot post-expiry reminder is enabled. pendingRemindersEnabled (boolean, required) - Master toggle for pending-request reminders. pendingReminderChips (integer[], required) - Days after a request is sent to send pending-request reminders. Response statuses: 200, 400, 401, 404, 422 --- # Update exemption-reminder settings PATCH /organization-settings/exemption-reminders Source: https://docs.trykintsugi.com/reference/2026-10-06/update-exemption-reminder-settings PATCH /organization-settings/exemption-reminders Update exemption-reminder settings Updates the ECM exemption-reminder settings. Any subset of fields may be sent; absent fields are unchanged. The expiring enabledAt watermark is server-managed. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to change its settings. Category: Organization Settings Request body: expiringRemindersEnabled (boolean) - Master toggle for expiring-exemption reminders. Absent means no change. expiringReminderChips (integer[]) - Days before expiry to send reminders. Must contain at least one positive value. postExpiryReminderEnabled (boolean) - Whether the one-shot post-expiry reminder is enabled. Absent means no change. pendingRemindersEnabled (boolean) - Master toggle for pending-request reminders. Absent means no change. pendingReminderChips (integer[]) - Days after a request is sent to send reminders. Must contain at least one positive value. Response fields: expiringRemindersEnabled (boolean, required) - Master toggle for expiring-exemption reminders. expiringReminderChips (integer[], required) - Days before expiry to send expiring-exemption reminders. expiringEnabledAt (string) - Server-managed watermark stamped the first time expiring reminders are turned on; null means they never have been. It is not cleared when reminders are turned off, so a non-null value does not mean they are on now — read `expiringRemindersEnabled` for the current state. postExpiryReminderEnabled (boolean, required) - Whether the one-shot post-expiry reminder is enabled. pendingRemindersEnabled (boolean, required) - Master toggle for pending-request reminders. pendingReminderChips (integer[], required) - Days after a request is sent to send pending-request reminders. Response statuses: 200, 400, 401, 403, 404, 422 --- # List organizations GET /organizations Source: https://docs.trykintsugi.com/reference/2026-10-06/list-organizations GET /organizations List organizations List the organizations your credential can access, keyset-paginated and ordered by name. A portfolio credential lists every organization it owns; narrow to one with an `Organization-Id` selector. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Optionally filter by `search` (name substring) and `status`. Each row is lean by default; pass `include=details` to embed the directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date) under `details` in the same call. Pass `expand=filingMetrics` to embed each organization's filing rollup (total, filed, pending approval, overdue and total liability) under `filingMetrics`. Category: Organizations Query parameters: search (string) - Case-insensitive substring match on the organization name. status (PublicOrganizationStatusEnum) - Filter to organizations with this status. allowed values: ACTIVE, ARCHIVED include (OrganizationInclude[]) - Optional expansions to embed on each row. Pass `details` to include the directory-detail fields under `details`; omitted otherwise. allowed values: details expand (OrganizationExpand[]) - Optional computed values to embed on each row. Pass `filingMetrics` to include the filing rollup under `filingMetrics`; omitted otherwise. allowed values: filingMetrics limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (OrganizationListItem[], required) - Organizations on this page, in the page's sort order (name). id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string) - Company state or province code, or null if unset. [truncated, see the reference page] --- # Create an organization POST /organizations Source: https://docs.trykintsugi.com/reference/2026-10-06/create-an-organization POST /organizations Create an organization Create a new organization. A portfolio credential links the new organization to its portfolio, so it enters that credential's scope. Admin or Owner only: returns 403 if your credential belongs to the portfolio but is not permitted to create organizations in it. Returns the created organization. Category: Organizations Request body: name (string, required) - Display name of the organization. isTest (boolean) - Whether this is a test organization. Defaults to false. A portfolio-authenticated create under a test partner always persists a test organization, even if this is false. A user-session create still honors the submitted flag. billingMode (PublicBillingMode) - How the new client is billed under the portfolio. Portfolio credentials only. Ignored when the portfolio already has a billing type (the client inherits it) and for a test portfolio. allowed values: PARTNER_MANAGED, CLIENT_MANAGED businessWebsites (string[]) - Company or storefront website URLs for the new client. Portfolio credentials only. At most 10 unique URLs. A URL without a scheme is stored as https. Duplicates are dropped. Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string) - Company state or province code, or null if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) [truncated, see the reference page] --- # Summarize your organizations GET /organizations/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-your-organizations GET /organizations/summary Summarize your organizations Aggregate counts across every organization your credential can access: the total, how many are active, and how many distinct NAICS industries they span. Category: Organizations Response fields: total (integer, required) - Total number of organizations you can access. active (integer, required) - Number of those organizations that are active. industries (integer, required) - Number of distinct NAICS industries across those organizations. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get an organization by id GET /organizations/{org_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-an-organization-by-id GET /organizations/{org_id} Get an organization by id Fetch a single organization by id. Returns 404 if the organization does not exist or your credential cannot access it. An organization you cannot access and one that does not exist return the same 404, so the API never confirms an id exists. Lean by default; pass `include=details` to embed the directory-detail fields under `details`. Category: Organizations Path parameters: org_id (string, required) - The unique identifier of the organization. Query parameters: include (OrganizationInclude[]) - Optional expansions to embed. Pass `details` to include the directory-detail fields under `details`; omitted otherwise. allowed values: details Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string) - Company state or province code, or null if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) einMasked (string, required) - Employer Identification Number with all but the last four digits masked, or null if no EIN is on file. industry (string, required) - NAICS industry code, or null if not captured. primaryContactName (string, required) - Business contact name. Empty string if unset. primaryContactEmail (string, required) - Business contact email. Empty string if unset. [truncated, see the reference page] --- # Update an organization PATCH /organizations/{org_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-an-organization PATCH /organizations/{org_id} Update an organization Update an organization's name. Address and business-profile fields are updated through `PATCH /organization-details`. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to change it. Returns 404 if the organization does not exist or your credential cannot access it. Category: Organizations Path parameters: org_id (string, required) - The unique identifier of the organization. Request body: name (string, required) - New display name for the organization. Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string) - Company state or province code, or null if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) einMasked (string, required) - Employer Identification Number with all but the last four digits masked, or null if no EIN is on file. industry (string, required) - NAICS industry code, or null if not captured. primaryContactName (string, required) - Business contact name. Empty string if unset. primaryContactEmail (string, required) - Business contact email. Empty string if unset. registeredStates (integer, required) - Number of states the organization has registrations in. [truncated, see the reference page] --- # Archive an organization POST /organizations/{org_id}/archive Source: https://docs.trykintsugi.com/reference/2026-10-06/archive-an-organization POST /organizations/{org_id}/archive Archive an organization Archive an organization, capturing a churn reason. This cascades: connections are archived, API keys deleted, and any billing subscription cancelled. `notes` is required when `reason` is OTHER. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to archive it. Returns 404 if the organization does not exist or your credential cannot access it. Category: Organizations Path parameters: org_id (string, required) - The unique identifier of the organization. Request body: reason (PublicArchivalReasonEnum, required) - Why the organization is being archived. allowed values: BILLING_PRICING, ONBOARDING_FRICTION, PRODUCT_FIT, DATA_ACCURACY_TRUST, TECHNICAL_SETUP_ISSUES, RESPONSIVENESS_SUPPORT, INTERNAL_CHANGES, TIMING_READINESS, MOVED_TO_COMPETITOR, NO_LONGER_NEEDED, OTHER notes (string) - Free-text detail. Required when reason is OTHER. Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string) - Company state or province code, or null if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) einMasked (string, required) - Employer Identification Number with all but the last four digits masked, or null if no EIN is on file. industry (string, required) - NAICS industry code, or null if not captured. [truncated, see the reference page] --- # List physical presences GET /physical-nexus Source: https://docs.trykintsugi.com/reference/2026-10-06/list-physical-presences GET /physical-nexus List physical presences Returns a keyset page of the physical presences recorded for organizations your credential owns. Defaults to country, then state, then category order; sort with `orderBy`/`order`, and omit `orderBy` to page in that default order. Send `Organization-Id`, `Connection-Id`, or `Entity-Id` to narrow to one organization. A cursor is valid only for the sort, filters and organization scope that issued it. Category: Physical nexus Query parameters: orderBy (PublicPhysicalNexusSortEnum) - Field to sort by. Omit to page in the default country, then state, then category order. allowed values: countryCode, stateCode, category, startDate, endDate, createdAt order (PublicPhysicalNexusSortOrder) - Sort direction. Applies only when `orderBy` is set. allowed values: asc, desc countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes. Matches any listed value. stateCode (string) - Comma-separated state or province codes. Matches any listed value. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (PhysicalNexus[], required) - Physical nexus rows on this page. id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. organizationHasTransactions (boolean, required) - Whether the owning organization has any transactions. Editing a closed presence would move a date that nexus was already calculated against, so clients disable editing when this is `true` and `endDate` is set. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. category (PublicPhysicalNexusCategoryEnum, required) - Kind of physical presence this record describes. Which categories a jurisdiction accepts varies; get the catalog from `GET /physical-nexus/categories`. Ignore unrecognized values. [truncated, see the reference page] --- # Record a physical presence POST /physical-nexus Source: https://docs.trykintsugi.com/reference/2026-10-06/record-a-physical-presence POST /physical-nexus Record a physical presence Record a physical presence in one jurisdiction. Recording a presence can establish nexus there, so the jurisdiction's exposure is recalculated. One record exists per organization, jurisdiction and category: a second create for the same three returns 200. A category the jurisdiction does not accept returns 400; get the accepted set from `GET /physical-nexus/categories`. Category: Physical nexus Request body: countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. category (PublicPhysicalNexusCategoryEnum, required) - Kind of physical presence to record. A category the jurisdiction does not accept returns 400; get the accepted set from `GET /physical-nexus/categories`. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) startDate (string, required) - Date the physical presence began, as YYYY-MM-DD. endDate (string) - Date the physical presence ended, as YYYY-MM-DD. Omit it or send `null` while the presence is open-ended. Must not precede `startDate`. externalId (string) - Your identifier for this record in an external system. street1 (string) - Street address of the location. street2 (string) - Suite, unit, or other address detail. city (string) - City of the location. postalCode (string) - ZIP or postal code of the location. Response fields: id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. [truncated, see the reference page] --- # List the physical presence category catalog GET /physical-nexus/categories Source: https://docs.trykintsugi.com/reference/2026-10-06/list-the-physical-presence-category-catalog GET /physical-nexus/categories List the physical presence category catalog List the physical presence categories a jurisdiction accepts. Each `name` is a value `category` accepts on a create or an update, and `isCategoryAssigned` reports whether the organization already records that category in this jurisdiction. Because that flag is organization data, this route needs exactly one organization: send `Organization-Id`, `Connection-Id`, or `Entity-Id` if your credential reaches more than one. Category: Physical nexus Query parameters: countryCode (string) - ISO 3166-1 alpha-2 country of the jurisdiction. Defaults to `US`. stateCode (string) - State or province code within `countryCode`. Omit it for the country-level catalog, in which case no category reads as assigned. Response fields: name (PublicPhysicalNexusCategoryEnum, required) - The category value. Send it as `category` on a create or an update. Ignore unrecognized values. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) title (string, required) - Display label for this category. Empty if none is defined. description (string, required) - What this category covers. Empty if no description is defined. example (string, required) - Worked example of a presence in this category. Empty if none is defined. isCategoryAssigned (boolean, required) - Whether the resolved organization already records this category in the requested jurisdiction. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a physical presence GET /physical-nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-physical-presence GET /physical-nexus/{physical_nexus_id} Get a physical presence Returns one physical presence. Searches every organization your credential owns, so no selector is needed for a known id. Returns 404 if the record does not exist or is not visible to your credential. Category: Physical nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus. Response fields: id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. organizationHasTransactions (boolean, required) - Whether the owning organization has any transactions. Editing a closed presence would move a date that nexus was already calculated against, so clients disable editing when this is `true` and `endDate` is set. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. category (PublicPhysicalNexusCategoryEnum, required) - Kind of physical presence this record describes. Which categories a jurisdiction accepts varies; get the catalog from `GET /physical-nexus/categories`. Ignore unrecognized values. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) source (PublicPhysicalNexusSourceEnum, required) - What created this record. `USER` for one you recorded through the API or the app; `DEEL` for one synced from the organization's Deel integration. Ignore unrecognized values. allowed values: USER, DEEL startDate (string, required) - Date the physical presence began, as YYYY-MM-DD. endDate (string) - Date the physical presence ended, as YYYY-MM-DD. `null` while it is open-ended. [truncated, see the reference page] --- # Update a physical presence PATCH /physical-nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-physical-presence PATCH /physical-nexus/{physical_nexus_id} Update a physical presence Update a physical presence. A field you omit, or send as null, is left unchanged. Changing the category or the dates can change whether the jurisdiction has nexus, so its exposure is recalculated. The jurisdiction itself is not editable: delete the record and create it under the country and state you want. A category the jurisdiction does not accept returns 400, and a category already recorded for this jurisdiction returns 409. Category: Physical nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus. Request body: category (PublicPhysicalNexusCategoryEnum) - New kind of physical presence. A category the jurisdiction does not accept returns 400. Omit it or send `null` to leave it unchanged. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) startDate (string) - New date the physical presence began. Omit it or send `null` to leave it unchanged. endDate (string) - New date the physical presence ended. Omit it or send `null` to leave it unchanged; this endpoint cannot reopen a closed presence. Must not precede the effective `startDate`. street1 (string) - New street address. Omit it or send `null` to leave it unchanged, or an empty string to clear it. street2 (string) - New suite, unit, or other address detail. Omit it or send `null` to leave it unchanged, or an empty string to clear it. city (string) - New city. Omit it or send `null` to leave it unchanged, or an empty string to clear it. postalCode (string) - New ZIP or postal code. Omit it or send `null` to leave it unchanged, or an empty string to clear it. Response fields: id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. [truncated, see the reference page] --- # Delete a physical presence DELETE /physical-nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/delete-a-physical-presence DELETE /physical-nexus/{physical_nexus_id} Delete a physical presence Delete a physical presence. Removing it can end nexus in that jurisdiction, so the jurisdiction's exposure is recalculated. Returns 404 if the record does not exist or belongs to an organization your credential cannot access. Category: Physical nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # List products GET /products Source: https://docs.trykintsugi.com/reference/2026-10-06/list-products GET /products List products List products, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Filter with `status`, `source` (comma-separated), `search`, `productCategory` and `productSubcategory`, and sort with `orderBy`/`order`; omit `orderBy` to page in the default id order. Pass `limit` and the opaque `cursor` from a prior response to page. A cursor is only valid for the sort, filters AND organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Products Query parameters: orderBy (PublicProductSortEnum) - Field to sort by. Omit to page in the default id order (fastest); the other keys sort the whole matching set. allowed values: name, status, createdAt, externalId, source order (PublicProductSortOrder) - Sort direction. Applies only when `orderBy` is set. allowed values: asc, desc status (string) - Comma-separated approval statuses; matches any of them. source (string) - Comma-separated source systems; matches any of them. search (string) - Search over product id, externalId, name and description. id and externalId must match exactly; name and description match a case-insensitive substring. productCategory (PublicProductCategoryEnum) - Tax category to filter by. Matches every product in the category regardless of subcategory; combine with productSubcategory to narrow. allowed values: Physical, Digital, Misc, Services productSubcategory (string) - Tax subcategory display label to filter by (e.g. 'General Clothing'). An unrecognized label matches no products. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Product[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for the product. organizationId (string, required) - Organization the product belongs to. Send it as `Organization-Id` to scope a request to this product. organizationName (string) - Display name of the organization the product belongs to. `null` when the organization has no name set. externalId (string, required) - Your stable identifier for the product, as supplied on create. [truncated, see the reference page] --- # Create a product POST /products Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-product POST /products Create a product Create a product in the resolved organization. Idempotent on `externalId` and `source`: sending the same values again returns the existing product unchanged and responds `200` instead of creating a duplicate. If the match is a product you previously deleted, it is restored (not duplicated) so its tax history stays attached to it; a restored product re-enters classification and its `status` returns to `PENDING`, so it is not used in tax calculation until it is approved again. The product is not otherwise updated by this call; use `PATCH /products/{productId}` to update. `source` accepts only the curated public values. `status` does not accept ARCHIVED; archive an existing product with `DELETE /products/{productId}`. Category: Products Request body: externalId (string, required) - Your stable identifier for the product. Creating another product with the same externalId and source returns the existing product (200) instead of a duplicate; use PATCH to update it. The same externalId can still appear on products synced from your connections. name (string, required) - Human-readable product name. description (string) - Optional product description. status (PublicProductCreateStatusEnum) - Approval status of the product's tax classification. ARCHIVED is not accepted here: archive an existing product with DELETE /products/{id}. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING productCategory (PublicProductCategoryEnum, required) - Top-level tax category for the product. allowed values: Physical, Digital, Misc, Services productSubcategory (string, required) - Tax subcategory display label within the category (e.g. 'General Clothing', 'B2B SaaS'). Together with productCategory it resolves to a product tax code; an unrecognized pair returns 400. taxExempt (boolean, required) - Whether the product is treated as tax-exempt by tax calculation. This is the effective exemption flag applied to transactions. source (string) - Origin system of the product (e.g. API, SHOPIFY). Defaults to OTHER. Must be a supported public source; unsupported values are rejected. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) [truncated, see the reference page] --- # Approve partially-approved products in bulk POST /products/bulk-approve Source: https://docs.trykintsugi.com/reference/2026-10-06/approve-partially-approved-products-in-bulk POST /products/bulk-approve Approve partially-approved products in bulk Approve partially-approved products in one organization, either by naming `productIds` (at most 100) or by `filters`. Provide exactly one of the two: sending both, or neither, returns 400. The approval is atomic: either every matched product is approved or none is. `approvedCount` and `skippedCount` report what actually changed, not how many you asked for. An id that is not partially-approved, does not exist, or belongs to an organization your credential cannot access is counted in `skippedCount`, never approved. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productIds (string[]) - Explicit product ids to approve (at most 100). Mutually exclusive with filters; provide exactly one of the two. An id that is not partially-approved, not found, or in an organization you cannot access is counted in skippedCount, never approved. filters (BulkApproveFilters) - Attribute filters selecting which partially-approved products to approve. Mutually exclusive with productIds; provide exactly one of the two. productCategory (PublicProductCategoryEnum) - Approve only products in this tax category. Omit to match any category. Combine with productSubcategory and/or source to narrow further. allowed values: Physical, Digital, Misc, Services productSubcategory (string) - Approve only products whose tax subcategory display label matches (e.g. 'General Clothing'). Omit to match any subcategory. source (string) - Approve only products from this origin system (e.g. API, SHOPIFY). Must be a supported public source; unsupported values are rejected. Omit to match any source. Response fields: approvedCount (integer, required) - Number of products moved to APPROVED by this request. skippedCount (integer, required) - Number of requested products left unchanged because they were not partially-approved, not found, or outside your access. Always 0 for a filter-based request. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Approve partially-approved products by category POST /products/bulk-approve-by-category Source: https://docs.trykintsugi.com/reference/2026-10-06/approve-partially-approved-products-by-category POST /products/bulk-approve-by-category Approve partially-approved products by category Approve EVERY partially-approved product in one organization that falls under the given `categories`, with one bulk update per category. Unlike `bulk-approve` (capped at 100 ids), this is how you approve a whole category without paging ids. Each `productCategory`/`productSubcategory` pair must resolve to a product tax code or the request returns 400. `approvedCount` is the total actually moved to APPROVED across all categories. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: categories (ProductCategorySelector[], required) - Category/subcategory pairs to approve. Every partially-approved product in each pair is moved to APPROVED. Provide at least one. productCategory (PublicProductCategoryEnum, required) - Top-level tax category to approve products in. allowed values: Physical, Digital, Misc, Services productSubcategory (string, required) - Tax subcategory display label within the category (e.g. 'General Clothing'). Together with productCategory it must resolve to a product tax code; an unrecognized pair returns 400. Response fields: approvedCount (integer, required) - Total number of products moved to APPROVED across all requested categories. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get the resolved organization's in-progress bulk-classification import GET /products/bulk-classifications/active-review Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-resolved-organization-s-in-progress-bulk-classification-import GET /products/bulk-classifications/active-review Get the resolved organization's in-progress bulk-classification import Return the resolved organization's bulk-classification import that is still awaiting a decision or applying, or `null` when there is none. Lets a client restore an in-progress review after losing the import id (a page reload). Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED productsToUpdate (integer, required) - Products this import will update once confirmed. productsToSkip (integer, required) - Rows that failed validation and will not be applied. productsIgnored (integer, required) - Rows that matched no change (already at the target category). skipReasons (ProductBulkClassificationSkipReasonCount[], required) - Skipped-row counts, broken down by reason. reason (PublicProductBulkSkipReasonEnum, required) - Why a row in a bulk-classification CSV was skipped rather than applied. allowed values: INVALID_PRODUCT, INVALID_CATEGORY, INVALID_SUBCATEGORY, INVALID_CATEGORY_AND_SUBCATEGORY, INVALID_APPROVAL_STATUS, CONFLICT count (integer, required) - Number of rows skipped for this reason. hasRejectedArtifact (boolean, required) - Whether a downloadable file of rejected rows exists. hasPreviewArtifact (boolean, required) - Whether a before/after preview is available. confirmedBy (string) - Id of the user who confirmed this import, or null if unconfirmed. confirmedAt (string) - When this import was confirmed, as an RFC-3339 UTC timestamp; null if unconfirmed. progressImported (integer) - Rows successfully applied so far; null before the apply is confirmed. progressRows (integer) - Total rows claimed for apply; null before the apply is confirmed. progressFailed (integer) - Rows that failed to apply so far; null before the apply is confirmed. [truncated, see the reference page] --- # Cancel a bulk-classification import POST /products/bulk-classifications/{import_id}/cancel Source: https://docs.trykintsugi.com/reference/2026-10-06/cancel-a-bulk-classification-import POST /products/bulk-classifications/{import_id}/cancel Cancel a bulk-classification import Cancel a bulk-classification import before it is confirmed. Returns 404 if the import does not exist or belongs to an organization your credential cannot access, and 409 if it cannot be cancelled in its current state. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED alreadyCancelled (boolean) - True when this import was already cancelled. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Confirm a bulk-classification import POST /products/bulk-classifications/{import_id}/confirm Source: https://docs.trykintsugi.com/reference/2026-10-06/confirm-a-bulk-classification-import POST /products/bulk-classifications/{import_id}/confirm Confirm a bulk-classification import Confirm a review-ready bulk-classification import and queue it to apply. `idempotencyKey` makes a retried confirm safe: resending the same key returns the same result rather than confirming twice. Returns 409 if the import is not review-ready, has no valid rows, or a different `idempotencyKey` was already recorded for it. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Request body: idempotencyKey (string, required) - A caller-chosen key. Resending the same key for this import returns the same confirmation instead of confirming twice. Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED confirmedBy (string) - Id of the user who confirmed this import, or null if unconfirmed. alreadyConfirmed (boolean) - True when this confirm resent an idempotency key that was already recorded, rather than confirming for the first time. Response statuses: 202, 400, 401, 403, 404, 409, 422, 503 --- # Get a bulk-classification import's before/after preview GET /products/bulk-classifications/{import_id}/preview Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-bulk-classification-import-s-before-after-preview GET /products/bulk-classifications/{import_id}/preview Get a bulk-classification import's before/after preview Return one page of the before/after tax-category preview for a bulk-classification import. Returns 404 if the import does not exist or belongs to an organization your credential cannot access, and 503 if the preview content is temporarily unavailable. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Query parameters: page (integer) size (integer) Response fields: importId (string, required) - The unique identifier of this import. page (integer, required) - The page number returned, starting at 1. size (integer, required) - Rows requested per page. total (integer, required) - Total previewable rows across all pages. items (ProductBulkClassificationPreviewRow[], required) - This page's rows. productId (string, required) - The unique identifier of the product. productName (string) - The product's name; null if not resolvable. externalId (string) - Your identifier for the product; null if not resolvable. beforeCategory (string) - Current tax category; null if the product is new. afterCategory (string) - Tax category this row will change the product to. beforeSubcategory (string) - Current tax subcategory; null if the product is new. afterSubcategory (string) - Tax subcategory this row will change the product to. beforeStatus (string) - Current classification status; null if the product is new. afterStatus (string) - Classification status this row will change the product to. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Get a bulk-classification import's rejected-rows file GET /products/bulk-classifications/{import_id}/rejected-file Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-bulk-classification-import-s-rejected-rows-file GET /products/bulk-classifications/{import_id}/rejected-file Get a bulk-classification import's rejected-rows file Return download instructions for the rows rejected from a bulk-classification import. Returns 404 if the import does not exist, belongs to an organization your credential cannot access, or has no rejected-rows file. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: downloadUrl (string, required) - Presigned URL to download the rejected rows; empty when the content is returned inline via `inlineContentBase64` instead. expiresInSeconds (integer, required) - Seconds until `downloadUrl` expires. inlineContentBase64 (string) - Base64-encoded rejected-rows content, when small enough to return inline instead of via `downloadUrl`. downloadName (string) - Suggested filename for the downloaded content. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Get a bulk-classification import's review state GET /products/bulk-classifications/{import_id}/review Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-bulk-classification-import-s-review-state GET /products/bulk-classifications/{import_id}/review Get a bulk-classification import's review state Return the validation summary and, once confirmed, the apply progress for a bulk-classification import. Returns 404 if the import does not exist or belongs to an organization your credential cannot access. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED productsToUpdate (integer, required) - Products this import will update once confirmed. productsToSkip (integer, required) - Rows that failed validation and will not be applied. productsIgnored (integer, required) - Rows that matched no change (already at the target category). skipReasons (ProductBulkClassificationSkipReasonCount[], required) - Skipped-row counts, broken down by reason. reason (PublicProductBulkSkipReasonEnum, required) - Why a row in a bulk-classification CSV was skipped rather than applied. allowed values: INVALID_PRODUCT, INVALID_CATEGORY, INVALID_SUBCATEGORY, INVALID_CATEGORY_AND_SUBCATEGORY, INVALID_APPROVAL_STATUS, CONFLICT count (integer, required) - Number of rows skipped for this reason. hasRejectedArtifact (boolean, required) - Whether a downloadable file of rejected rows exists. hasPreviewArtifact (boolean, required) - Whether a before/after preview is available. confirmedBy (string) - Id of the user who confirmed this import, or null if unconfirmed. confirmedAt (string) - When this import was confirmed, as an RFC-3339 UTC timestamp; null if unconfirmed. progressImported (integer) - Rows successfully applied so far; null before the apply is confirmed. progressRows (integer) - Total rows claimed for apply; null before the apply is confirmed. progressFailed (integer) - Rows that failed to apply so far; null before the apply is confirmed. [truncated, see the reference page] --- # Queue products for reclassification POST /products/bulk-classify Source: https://docs.trykintsugi.com/reference/2026-10-06/queue-products-for-reclassification POST /products/bulk-classify Queue products for reclassification Queue this credential's products for AI tax reclassification. By default it covers every organization you own; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. For each organization, products whose classification failed or is only partially approved are flagged and a classification batch is enqueued to run asynchronously. Returns 202 with `orgsQueued`, the number of organizations queued — the work itself completes in the background. Category: Products Response fields: orgsQueued (integer, required) - Number of organizations whose products were queued for reclassification. With no selector this is every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # List the product category catalog GET /products/categories Source: https://docs.trykintsugi.com/reference/2026-10-06/list-the-product-category-catalog GET /products/categories List the product category catalog List every tax category and the subcategory labels valid under it. Use it to build category/subcategory pickers: the `category` and each `label` are the exact values `productCategory` and `productSubcategory` accept on create, update and recategorize. The catalog is the same for every caller. Category: Products Response fields: category (PublicProductCategoryEnum, required) - Top-level tax category. Send it as `productCategory` on writes. allowed values: Physical, Digital, Misc, Services subcategories (ProductSubcategory[], required) - Subcategories valid under this category. Never empty. label (string, required) - Subcategory display label. Send it as `productSubcategory`, paired with the category, on create/patch to resolve a product tax code. description (string, required) - What this subcategory covers for sales-tax purposes. example (string, required) - Example products or services in this subcategory. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Categorize and approve products POST /products/categorize-approve Source: https://docs.trykintsugi.com/reference/2026-10-06/categorize-and-approve-products POST /products/categorize-approve Categorize and approve products Assign a `productCategory`/`productSubcategory` to the named products AND set them APPROVED, in one call. Unlike `bulk-approve` (which only moves partially-approved products), this classifies and signs off any products you name, at most 100. Every id must belong to the resolved organization; an id that does not exist or is in an organization you cannot access returns 404 and nothing is changed. The category/subcategory pair must resolve to a product tax code or the request returns 400. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productIds (string[], required) - Products to categorize and approve (at most 100). Every id must belong to the resolved organization; an unknown id returns 404 and nothing is changed. productCategory (PublicProductCategoryEnum, required) - Tax category to assign to every product. allowed values: Physical, Digital, Misc, Services productSubcategory (string, required) - Tax subcategory display label to assign (e.g. 'General Clothing'). Together with productCategory it must resolve to a product tax code; an unrecognized pair returns 400. Response fields: updatedCount (integer, required) - Number of products that were assigned the category/subcategory and moved to APPROVED. Equals the number of distinct ids you sent. Response statuses: 200, 400, 401, 403, 404, 422 --- # Summarize product classification progress GET /products/classification-progress Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-product-classification-progress GET /products/classification-progress Summarize product classification progress Count products by classification outcome across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Category: Products Response fields: total (integer, required) - Product count across the resolved organizations. classified (integer, required) - Products with APPROVED classification status. pending (integer, required) - Products with PENDING or PARTIALLY_APPROVED classification status. failed (integer, required) - Products where classification failed. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Check whether bulk classification can run GET /products/classification-status Source: https://docs.trykintsugi.com/reference/2026-10-06/check-whether-bulk-classification-can-run GET /products/classification-status Check whether bulk classification can run Report whether `POST /products/bulk-classify` is worth running, across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `canClassify` is true only when `totalProducts` meets `minProducts` and at least one product needs classification work: pending, or a status `POST /products/bulk-classify` would reset and re-run. Category: Products Query parameters: minProducts (integer) - Minimum product count required for `canClassify` to be true. Response fields: canClassify (boolean, required) - Whether POST /products/bulk-classify is worth running: enough products exist and at least one needs classification work, meaning it is pending or is a status bulk-classify would reset and re-run (partially approved or previously failed classification). totalProducts (integer, required) - Product count across the resolved organizations. hasPendingProducts (boolean, required) - Whether any resolved organization has a product in PENDING status. minProducts (integer, required) - The product count `totalProducts` must meet for `canClassify` to be true. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List product configurations GET /products/configs Source: https://docs.trykintsugi.com/reference/2026-10-06/list-product-configurations GET /products/configs List product configurations List product tax-category overrides, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Unsorted and unfiltered: pages walk in id order. Category: Products Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (ProductConfig[], required) - The results on this page. Empty when there are none. id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. isDefault (boolean, required) - Whether this is the organization's default configuration, applied when no other configuration matches a product. At most one configuration per organization may be the default. nextCursor (string) - Opaque cursor for the next page. `null` when this is the last page. Send it back as `cursor`; do not parse it. previousCursor (string) - Opaque cursor for the previous page. `null` when this is the first page. Send it back as `cursor`; do not parse it. hasMore (boolean) - Whether a page exists after this one. hasPrevious (boolean) - Whether a page exists before this one. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Create a product configuration POST /products/configs Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-product-configuration POST /products/configs Create a product configuration Create a product tax-category override for the resolved organization. `primaryProductCategory` and `primaryProductSubcategory` must resolve to a supported product tax code, or the request returns 400. At most one configuration per organization may set `isDefault`; creating a new default clears the previous one. Returns 409 if a configuration or blocklist entry already exists for the resolved tax code. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category. Must resolve to a supported tax code together with `primaryProductSubcategory`. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label, e.g. from `GET /products/categories`. aiEnabled (boolean) - Let the classifier choose among tax codes under this category rather than always applying the one resolved code. productDescription (string) - Free-text note about this configuration. isDefault (boolean) - Make this the organization's default configuration. Creating a new default clears the previous one. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. [truncated, see the reference page] --- # List blocklisted product codes GET /products/configs/blocklist Source: https://docs.trykintsugi.com/reference/2026-10-06/list-blocklisted-product-codes GET /products/configs/blocklist List blocklisted product codes List product tax codes excluded from onboarding suggestions, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Category: Products Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (ProductConfigBlocklistEntry[], required) - The results on this page. Empty when there are none. id (string, required) - The unique identifier of this blocklist entry. organizationId (string, required) - The organization this blocklist entry belongs to. productCodeName (string, required) - The blocklisted product tax code. nextCursor (string) - Opaque cursor for the next page. `null` when this is the last page. Send it back as `cursor`; do not parse it. previousCursor (string) - Opaque cursor for the previous page. `null` when this is the first page. Send it back as `cursor`; do not parse it. hasMore (boolean) - Whether a page exists after this one. hasPrevious (boolean) - Whether a page exists before this one. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Add a product code to the blocklist POST /products/configs/blocklist Source: https://docs.trykintsugi.com/reference/2026-10-06/add-a-product-code-to-the-blocklist POST /products/configs/blocklist Add a product code to the blocklist Exclude a product tax code from onboarding suggestions for the resolved organization. Idempotent: blocklisting an already-blocklisted code returns 200 with the existing entry rather than an error or a second 201. Returns 400 if `productCodeName` is not a recognized product tax code, and 409 if it already has a configuration (remove the configuration first). Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productCodeName (string, required) - The product tax code to exclude from onboarding suggestions. Response fields: id (string, required) - The unique identifier of this blocklist entry. organizationId (string, required) - The organization this blocklist entry belongs to. productCodeName (string, required) - The blocklisted product tax code. Response statuses: 200, 201, 400, 401, 403, 404, 409, 422 --- # Remove a product code from the blocklist DELETE /products/configs/blocklist/{product_code_name} Source: https://docs.trykintsugi.com/reference/2026-10-06/remove-a-product-code-from-the-blocklist DELETE /products/configs/blocklist/{product_code_name} Remove a product code from the blocklist Remove a product tax code from the blocklist. Returns 404 if it is not on the blocklist for the resolved organization. Category: Products Path parameters: product_code_name (string, required) - The product tax code to remove from the blocklist. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Create product configurations in bulk POST /products/configs/bulk Source: https://docs.trykintsugi.com/reference/2026-10-06/create-product-configurations-in-bulk POST /products/configs/bulk Create product configurations in bulk Create several product tax-category overrides for the resolved organization in one call. All entries succeed together, or none do: if any entry's category/subcategory does not resolve to a supported product tax code, or two entries (or an entry and an existing configuration) resolve to the same one, the whole request returns 400 or 409 and nothing is created. At most one entry across the whole request may set `isDefault`. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productConfigs (ProductConfigCreate[], required) - The configurations to create. All succeed together, or none do. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category. Must resolve to a supported tax code together with `primaryProductSubcategory`. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label, e.g. from `GET /products/categories`. aiEnabled (boolean) - Let the classifier choose among tax codes under this category rather than always applying the one resolved code. productDescription (string) - Free-text note about this configuration. isDefault (boolean) - Make this the organization's default configuration. Creating a new default clears the previous one. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. [truncated, see the reference page] --- # Get a product configuration by id GET /products/configs/{config_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-product-configuration-by-id GET /products/configs/{config_id} Get a product configuration by id Fetch a single product configuration by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Products Path parameters: config_id (string, required) - The unique identifier of the product configuration. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. isDefault (boolean, required) - Whether this is the organization's default configuration, applied when no other configuration matches a product. At most one configuration per organization may be the default. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Update a product configuration PATCH /products/configs/{config_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-product-configuration PATCH /products/configs/{config_id} Update a product configuration Update a product configuration's editable fields. This is a partial update: only the fields you send change; any field you omit is left as-is. Send `primaryProductCategory` and `primaryProductSubcategory` together to change the category; sending only one returns 400. Returns 404 if the configuration does not exist or belongs to an organization your credential cannot access, and 409 if the change would duplicate another configuration's tax code. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Path parameters: config_id (string, required) - The unique identifier of the product configuration. Request body: primaryProductCategory (PublicProductCategoryEnum) - New top-level tax category. Send together with `primaryProductSubcategory`. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string) - New tax subcategory display label. aiEnabled (boolean) - Let the classifier choose among tax codes under this category. productDescription (string) - Free-text note about this configuration. isDefault (boolean) - Make this the organization's default configuration. Creating a new default clears the previous one. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. [truncated, see the reference page] --- # Delete a product configuration DELETE /products/configs/{config_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/delete-a-product-configuration DELETE /products/configs/{config_id} Delete a product configuration Delete a product configuration by id. Returns 404 if it does not exist or belongs to an organization your credential cannot access. Category: Products Path parameters: config_id (string, required) - The unique identifier of the product configuration. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Break down products by category GET /products/overview Source: https://docs.trykintsugi.com/reference/2026-10-06/break-down-products-by-category GET /products/overview Break down products by category Count products by organization, tax category and subcategory across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Each row is one organization's count for a category/subcategory. Archived products are never counted. Rows are ordered by organization, then category, then subcategory. Category: Products Response fields: organizationId (string, required) - Organization this count is for. Send it as `Organization-Id` to scope a follow-up request to this organization's products. productCategory (string, required) - Derived display category for the product tax code. productSubcategory (string, required) - Derived display subcategory for the product tax code. count (integer, required) - Number of products in scope with this category/subcategory. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Recategorize products in bulk POST /products/recategorize Source: https://docs.trykintsugi.com/reference/2026-10-06/recategorize-products-in-bulk POST /products/recategorize Recategorize products in bulk Move products in one organization from one category/subcategory to another. Every product matching `existingCategory`/`existingSubcategory` is reassigned to `newCategory`/`newSubcategory`, which must resolve to a supported tax code or the request returns 400. Pass `statusList` to move only products currently in those approval statuses. The reassignment runs asynchronously; the response is a 202 with `orgsQueued`. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: existingCategory (PublicProductCategoryEnum, required) - Current top-level tax category of the products to move. allowed values: Physical, Digital, Misc, Services existingSubcategory (string, required) - Current tax subcategory display label of the products to move (e.g. 'General Clothing'). With existingCategory it selects which products recategorize. newCategory (PublicProductCategoryEnum, required) - New top-level tax category to assign to the matched products. allowed values: Physical, Digital, Misc, Services newSubcategory (string, required) - New tax subcategory display label to assign (e.g. 'Catering'). With newCategory it must resolve to a supported product tax code; an unrecognized pair returns 400. statusList (PublicProductStatusEnum[]) - Optional approval-status filter: only move products currently in one of these statuses. Omit to move every product matching the existing category/subcategory pair regardless of status. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED Response fields: orgsQueued (integer, required) - Number of organizations queued for recategorization. Always 1: a recategorize targets the single organization resolved from your credential and any `Organization-Id` selector. Response statuses: 202, 400, 401, 403, 404, 422 --- # Export products POST /products/reports/export Source: https://docs.trykintsugi.com/reference/2026-10-06/export-products POST /products/reports/export Export products Queue a products export for one organization. The report is generated asynchronously and a download link is emailed, so the response is a 202 rather than the file itself. An API-key credential must provide `email`; a first-party bearer session may omit it to send the report to its own account email. Returns 400 if the organization has disabled email delivery. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: email (string) - Address the generated report download link is emailed to. Required for an API-key credential (it has no session user). For a first-party bearer session it is optional: omit it to send the report to your own account email. Response fields: organizationId (string, required) - Organization the export was queued for. email (string, required) - Address the report download link will be emailed to. Response statuses: 202, 400, 401, 403, 404, 422 --- # Summarize products by status GET /products/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-products-by-status GET /products/summary Summarize products by status Count products by approval status across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Archived products are never counted. `total` is the sum of `statusCounts`. Category: Products Response fields: total (integer, required) - Total products in scope, the sum of `statusCounts`. Excludes archived products. statusCounts (ProductStatusCount[], required) - One entry per status present in scope. A status with no products is omitted rather than reported as zero. status (PublicProductStatusEnum, required) - The approval status this count is for. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED count (integer, required) - Number of products in scope with this status. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a product by id GET /products/{product_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-product-by-id GET /products/{product_id} Get a product by id Fetch a single product by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Products Path parameters: product_id (string, required) - The unique identifier of the product. Response fields: id (string, required) - Kintsugi's unique identifier for the product. organizationId (string, required) - Organization the product belongs to. Send it as `Organization-Id` to scope a request to this product. organizationName (string) - Display name of the organization the product belongs to. `null` when the organization has no name set. externalId (string, required) - Your stable identifier for the product, as supplied on create. sku (string[]) - SKUs associated with the product. An empty list when it has none. code (string, required) - Derived product tax code display name. name (string, required) - Human-readable product name. description (string) - Product description; an empty string when the product has none. status (PublicProductStatusEnum, required) - Approval status of the product's tax classification. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED productCategory (string, required) - Derived display category for the product's tax code. productSubcategory (string, required) - Derived display subcategory for the product's tax code. taxExempt (boolean, required) - Effective tax-exemption flag applied by tax calculation. sourceTaxExempt (boolean) - Raw tax-exempt signal reported by the source system (audit). `null` when the source system did not report a signal, which is distinct from an explicit `false`. source (string, required) - Origin system of the product (e.g. API, SHOPIFY). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) connectionId (string) - Identifier of the connection that produced the product. `null` when the product was not produced by a connection (e.g. created manually). storeName (string) - Display name of the connection (store) that produced the product. `null` when the product has no connection, or the connection has no store name set. [truncated, see the reference page] --- # Update a product PATCH /products/{product_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-product PATCH /products/{product_id} Update a product Update a product's editable fields. This is a partial update: only the fields you send with a non-null value change; any field you omit or send as null is left as-is. `externalId` must stay unique per organization; reusing another product's value returns 409. `productCategory` and `productSubcategory` must resolve to a supported tax code or the request returns 400. `taxExempt` is honored when the category is unchanged; on a recategorize the exemption is derived from the new category and the sent value is ignored, and an exempt category is always tax-exempt. `source` is not editable. Returns 404 if the product does not exist, is archived, or belongs to an organization your credential cannot access. Category: Products Path parameters: product_id (string, required) - The unique identifier of the product. Request body: externalId (string) - New stable identifier for the product. Must stay unique per organization and source; a value already used by another product returns 409 Conflict. Omit it or send null to leave it unchanged; an empty string is rejected. name (string) - New human-readable product name. Omit it or send null to leave it unchanged; an empty string is rejected. description (string) - New product description. Send an empty string to clear it. Omit it or send null to leave it unchanged. productCategory (PublicProductCategoryEnum) - New top-level tax category. Together with productSubcategory it resolves to a product tax code; an unrecognized pair returns 400. Omit it or send null to leave it unchanged. allowed values: Physical, Digital, Misc, Services productSubcategory (string) - New tax subcategory display label within the category (e.g. 'General Clothing'). Together with productCategory it resolves to a product tax code; an unrecognized pair returns 400. Omit it or send null to leave it unchanged; an empty string is rejected. status (PublicProductCreateStatusEnum) - New approval status of the product's tax classification. ARCHIVED is not accepted here: archive a product with DELETE /products/{id}. Omit it or send null to leave it unchanged. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING [truncated, see the reference page] --- # Archive a product DELETE /products/{product_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/archive-a-product DELETE /products/{product_id} Archive a product Archive a product. It is removed from this API: afterwards it is absent from `GET /products` and returns 404 from every read, exactly as a product that never existed does. The identity stays taken: creating a product again with the same `externalId` and `source` restores this product and returns it with `200`, and a transaction or sync that references the same `externalId` restores it too. Returns 404 if the product does not exist, is already archived, or belongs to an organization your credential cannot access. Category: Products Path parameters: product_id (string, required) - The unique identifier of the product. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Get the status of a public exemption request GET /public/exemption-requests/{token} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-status-of-a-public-exemption-request GET /public/exemption-requests/{token} Get the status of a public exemption request Read the status of the exemption request the link identifies: the jurisdictions the business requested a certificate for, their coverage status, and the certificates already uploaded. The link in the path is the only credential; no API key is needed. Returns 404 if the link is unknown and 410 if it is no longer available (completed, rejected, or expired). Category: Exemption Requests (Public) Path parameters: token (string, required) Response fields: jurisdictions (string[], required) - Jurisdictions the business requested a certificate for. jurisdictionStatuses (PublicJurisdictionStatus[], required) - Per-jurisdiction coverage status. state (string, required) - The jurisdiction (US state code). chipState (PublicJurisdictionChipState, required) - Derived badge state the page renders for this jurisdiction. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED uploadedCertificates (PublicUploadedCertificate[], required) - Certificates the purchaser has already uploaded. fileName (string, required) - Original file name the purchaser uploaded. submittedAt (string, required) - When the certificate was uploaded. statusPill (PublicCertificateStatusPill, required) - Display status of this certificate's review. Branch on this value. allowed values: SUBMITTED, REVIEW_IN_PROGRESS, APPROVED, REJECTED extractedJurisdictions (string[], required) - Jurisdictions detected on the certificate, if any. extractedCertificateType (string) - Certificate type detected on the document, or null if none was detected. requestStatusPill (PublicRequestStatusPill, required) - Request-level rollup status driving the confirmation headline. Branch on this value. allowed values: SUBMITTED, REVIEW_IN_PROGRESS, PARTIALLY_COMPLETED, APPROVED, REJECTED Response statuses: 200, 404, 410, 422 --- # Confirm uploaded certificates for an exemption request POST /public/exemption-requests/{token}/confirm-upload Source: https://docs.trykintsugi.com/reference/2026-10-06/confirm-uploaded-certificates-for-an-exemption-request POST /public/exemption-requests/{token}/confirm-upload Confirm uploaded certificates for an exemption request Confirm that files issued by a prior upload-urls call finished uploading to S3, so they can be processed. Send the `certificateImportId`s from that call. Returns 404 if an id is not part of this request, and 410 if the link is no longer available. Category: Exemption Requests (Public) Path parameters: token (string, required) Request body: certificateImportIds (string[], required) - The certificateImportIds whose uploads completed successfully. Response fields: confirmed (integer, required) - Number of uploads confirmed and queued for processing. Response statuses: 200, 400, 404, 410, 422 --- # Get the status of a public missing-certificate request GET /public/exemption-requests/{token}/missing-certificates Source: https://docs.trykintsugi.com/reference/2026-10-06/get-the-status-of-a-public-missing-certificate-request GET /public/exemption-requests/{token}/missing-certificates Get the status of a public missing-certificate request Read the status of the missing-certificate request the link identifies: the business and purchaser names, the jurisdictions a certificate is needed for, and their coverage status. The link in the path is the only credential. Returns 404 if the link is unknown and 410 if it is no longer available. Category: Missing Certificates (Public) Path parameters: token (string, required) Response fields: customerName (string, required) - The purchaser's name. sellerName (string, required) - The business that requested the certificate. jurisdictions (string[], required) - Jurisdictions a certificate is needed for. jurisdictionStatuses (PublicMissingCertificateJurisdictionStatus[], required) - Per-jurisdiction coverage status. state (string, required) - The jurisdiction (US state code). status (PublicMissingCertificateJurisdictionStatusEnum, required) - Coverage status for this jurisdiction. allowed values: PENDING, PROCESSING, SATISFIED, REJECTED reason (string) - Why the jurisdiction is not satisfied, when applicable. Response statuses: 200, 404, 410, 422 --- # Confirm uploaded certificates for a missing-certificate request POST /public/exemption-requests/{token}/missing-certificates/confirm-upload Source: https://docs.trykintsugi.com/reference/2026-10-06/confirm-uploaded-certificates-for-a-missing-certificate-request POST /public/exemption-requests/{token}/missing-certificates/confirm-upload Confirm uploaded certificates for a missing-certificate request Confirm that files issued by a prior upload-urls call finished uploading to S3, then run validation. Send the `certificateImportId`s from that call. Returns 404 if an id is not part of this request, and 410 if the link is no longer available. Category: Missing Certificates (Public) Path parameters: token (string, required) Request body: certificateImportIds (string[], required) - The certificateImportIds whose uploads completed successfully. Response fields: status (PublicMissingCertificateUploadStatusEnum, required) - Overall validation outcome across the confirmed uploads. allowed values: PROCESSING, SATISFIED, REJECTED reason (string) - Why the request is not satisfied, when applicable. results (PublicMissingCertificateJurisdictionResult[], required) - Per-upload validation outcomes. certificateImportId (string, required) - The confirmed upload this result is for. exemptionId (string) - The exemption created from this certificate, when satisfied. status (PublicMissingCertificateUploadStatusEnum, required) - Validation outcome for this upload. allowed values: PROCESSING, SATISFIED, REJECTED reason (string) - Why the upload was rejected, when applicable. Response statuses: 200, 400, 404, 410, 422 --- # Request presigned upload urls for a missing-certificate request POST /public/exemption-requests/{token}/missing-certificates/upload-urls Source: https://docs.trykintsugi.com/reference/2026-10-06/request-presigned-upload-urls-for-a-missing-certificate-request POST /public/exemption-requests/{token}/missing-certificates/upload-urls Request presigned upload urls for a missing-certificate request Request one presigned S3 upload target per file for a missing-certificate request. POST each file to its target, then call confirm-upload. Returns 400 if a file type is not supported, 404 if the link is unknown, and 410 if it is no longer available. Category: Missing Certificates (Public) Path parameters: token (string, required) Request body: files (PublicUploadFile[], required) - The files to request upload targets for. fileName (string, required) - Original filename including extension. mimeType (string, required) - Media type of the file. Response fields: files (PublicUploadUrl[], required) - One presigned upload target per requested file. fileName (string, required) - The file name this upload target is for. certificateImportId (string, required) - Id to send back to confirm-upload once the S3 POST succeeds. uploadUrlConfig (PublicPresignedUpload, required) - The presigned S3 POST for this file. url (string, required) - The S3 endpoint to POST the file to. fields (PublicUploadField[], required) - Form fields to include in the multipart POST, verbatim, alongside the file part. Send every entry as a form field named `key` with its `value`. key (string, required) - The form field name. value (string, required) - The form field value to send verbatim. Response statuses: 200, 400, 404, 410, 422 --- # Request presigned upload urls for an exemption request POST /public/exemption-requests/{token}/upload-urls Source: https://docs.trykintsugi.com/reference/2026-10-06/request-presigned-upload-urls-for-an-exemption-request POST /public/exemption-requests/{token}/upload-urls Request presigned upload urls for an exemption request Request one presigned S3 upload target per file. POST each file to its target, then call confirm-upload with the returned `certificateImportId`s. Returns 400 if a file type is not supported, 404 if the link is unknown, and 410 if it is no longer available. Category: Exemption Requests (Public) Path parameters: token (string, required) Request body: files (PublicUploadFile[], required) - The files to request upload targets for. fileName (string, required) - Original filename including extension. mimeType (string, required) - Media type of the file. Response fields: files (PublicUploadUrl[], required) - One presigned upload target per requested file. fileName (string, required) - The file name this upload target is for. certificateImportId (string, required) - Id to send back to confirm-upload once the S3 POST succeeds. uploadUrlConfig (PublicPresignedUpload, required) - The presigned S3 POST for this file. url (string, required) - The S3 endpoint to POST the file to. fields (PublicUploadField[], required) - Form fields to include in the multipart POST, verbatim, alongside the file part. Send every entry as a form field named `key` with its `value`. key (string, required) - The form field name. value (string, required) - The form field value to send verbatim. Response statuses: 200, 400, 404, 410, 422 --- # Download a report via an emailed link GET /public/reports/downloads/{download_token} Source: https://docs.trykintsugi.com/reference/2026-10-06/download-a-report-via-an-emailed-link GET /public/reports/downloads/{download_token} Download a report via an emailed link Redirect to a short-lived presigned URL for a completed report. The link token in the path is the only credential; no Api-Key or bearer token is needed or accepted. Returns 404 if the link is unknown or the report is not yet ready, and 410 if the link has expired. Category: Reports (Public) Path parameters: download_token (string, required) Response statuses: 307, 404, 410, 422 --- # Get a jurisdiction's registration form GET /registration-jurisdiction-fields Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-jurisdiction-s-registration-form GET /registration-jurisdiction-fields Get a jurisdiction's registration form Return the fields a jurisdiction requires on a registration: a JSON Schema plus UI metadata for rendering the form. This is reference data shared by every organization, but a valid credential is still required. The schema's property names match the `jurisdictionSpecificFields` you send on a registration create. When the jurisdiction needs no jurisdiction-specific fields, `defaultForm` is `true`, the schema is an empty object and `metadata` is `null`. Category: Registrations Query parameters: countryCode (string, required) - ISO 3166-1 alpha-2 country code. stateCode (string, required) - State or province code. Response fields: countryCode (string, required) - ISO 3166-1 alpha-2 country code the schema is for, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code the schema is for. defaultForm (boolean, required) - `true` when this jurisdiction requires no jurisdiction-specific fields and the generic registration form should be used. `jurisdictionFieldsJsonSchema` is then an empty object and `metadata` is `null`. jurisdictionFieldsJsonSchema (object, required) - JSON Schema for the fields this jurisdiction accepts under `jurisdictionSpecificFields`. Property names are camelCase. An empty object when `defaultForm` is `true`. metadata (JurisdictionFormMetadata) - UI metadata for rendering the form. `null` when `defaultForm` is `true`. title (string, required) - Heading to show above the form. portalWebsiteUrl (string) - Tax authority portal this jurisdiction's credentials sign in to. `null` when none is recorded. portalWebsiteLabel (string) - Display label for `portalWebsiteUrl`. `null` when none is recorded. helpArticles (HelpArticle[]) - Help-center links to guide the user through this jurisdiction. label (string, required) - Human-readable title of the help article. url (string, required) - Link to the help article. sstBannerEnabled (boolean, required) - Whether the form should show the Streamlined Sales Tax banner for this jurisdiction. filingFrequencies (string[]) - Filing frequencies to offer for this jurisdiction. Empty when the full standard set applies. securityQuestionsEnabled (boolean, required) - Whether the form collects security questions for this jurisdiction. [truncated, see the reference page] --- # List registration jurisdictions GET /registration-jurisdictions Source: https://docs.trykintsugi.com/reference/2026-10-06/list-registration-jurisdictions GET /registration-jurisdictions List registration jurisdictions List the country/state jurisdictions your organizations hold registrations in. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to narrow to one. The whole set is returned in one response. `status` takes a comma-separated list and keeps only jurisdictions with a registration in one of those statuses; omit it to include every status. Category: Registrations Query parameters: status (string) - Comma-separated lifecycle statuses; keeps jurisdictions matching any of them. Response fields: jurisdictions (RegistrationJurisdiction[], required) - Distinct country/state jurisdictions across the organizations in scope, ordered by country then state. Streamlined Sales Tax registrations are excluded. countryCode (string, required) - ISO 3166-1 alpha-2 country code the registration is held in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code within `countryCode`. An empty string for a country-level jurisdiction. stateName (string) - Display name of the state or province. An empty string for a country-level jurisdiction. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Preview registering a jurisdiction POST /registration-preflights Source: https://docs.trykintsugi.com/reference/2026-10-06/preview-registering-a-jurisdiction POST /registration-preflights Preview registering a jurisdiction Report what a DIRECT_REQUEST `POST /registrations` for a jurisdiction would do, without creating anything. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to say which organization it is for `result` is OK when a new registration would be opened, ABSORBED when an existing sales-tax registration would cover the jurisdiction instead (returned as `registration`), PLAN_UPGRADE_REQUIRED when the organization's plan does not include the registration, or SALES_TAX_REGISTRATION_REQUIRED when a retail delivery fee registration needs an active sales-tax registration in the jurisdiction first It assumes the jurisdiction has a nexus, like the register dialog, which only previews jurisdictions the organization is exposed in. A jurisdiction with no nexus reports OK This is read-only: it stores nothing and never creates a registration. Category: Registrations Request body: countryCode (string, required) - ISO 3166-1 alpha-2 country code to check, such as `US`, `CA` or `GB`. stateCode (string) - State or province code within `countryCode`. Omit it for a country-level check. taxType (PublicTaxTypeEnum) - Which taxes the prospective registration would cover. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE Response fields: result (PublicRegisterPreflightResultEnum, required) - OK to open a new registration, ABSORBED when a sales-tax registration would cover it, PLAN_UPGRADE_REQUIRED when the plan does not include it, or SALES_TAX_REGISTRATION_REQUIRED when the retail delivery fee needs an active sales-tax registration first. allowed values: OK, ABSORBED, PLAN_UPGRADE_REQUIRED, SALES_TAX_REGISTRATION_REQUIRED registration (Registration) - The existing sales-tax registration that would absorb this one. Present only when `result` is ABSORBED, `null` otherwise. id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. organizationName (string) - Display name of the organization the registration belongs to. `null` when the organization has no name set. Sort a list by it with `sort=organizationName`. [truncated, see the reference page] --- # List registrations GET /registrations Source: https://docs.trykintsugi.com/reference/2026-10-06/list-registrations GET /registrations List registrations List tax registrations, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Every filter takes a comma-separated list and matches any of the values you send. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page; `hasMore` and `hasPrevious` report whether a page exists that way. Pass `sort` and `order` to order the list; omit `sort` to keep the default order. None of the sort keys is index-backed, so sorting a large organization's registrations sorts the whole matching set. A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Registrations Query parameters: sort (PublicRegistrationSortEnum) - Field to sort by. Omit to keep the default ordering. `organizationName` orders by the owning organization's display name, which is useful only on a portfolio-wide list. None of the keys is index-backed, so sorting sorts the whole matching set on a large organization. allowed values: organizationName, countryCode, stateCode, registrationDate, status order (PublicRegistrationSortOrder) - Sort direction. Applies only when `sort` is set. Defaults to `asc`. allowed values: asc, desc status (string) - Comma-separated lifecycle statuses; matches any of them. countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any of them. stateCode (string) - Comma-separated state or province codes; matches any of them. Combine it with `countryCode` when a code is not unique across countries. filingFrequency (string) - Comma-separated filing frequencies; matches any of them. taxType (string) - Comma-separated tax types; matches any of them. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Registration[], required) - The registrations on this page. id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. [truncated, see the reference page] --- # Create a registration POST /registrations Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-registration POST /registrations Create a registration Register in one jurisdiction or record a registration you already hold. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to say which organization it belongs to `registrationImportType` chooses the kind of registration. REGULAR is the default and is a direct registration identified by `countryCode` and `stateCode`. OSS is an EU One Stop Shop scheme, identified by its member state instead. SST is the single Streamlined Sales Tax registration an organization may hold, covering the member states at once DIRECT_REQUEST asks Kintsugi to obtain a registration you do not yet hold, rather than recording one you already have. Kintsugi resolves the jurisdiction from `countryCode`, `stateCode` and `taxType`, opens the registration in PROCESSING for its team to complete, and requires a paid plan that includes managed registrations. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan that does not include managed registrations is refused with 403 FORBIDDEN. Use `POST /registration-preflights` first to see whether an existing registration would cover it An SST registration is write-only on this surface. It records the organization's Streamlined Sales Tax enrollment and sign-in, and unlike a REGULAR or OSS registration it is not returned by `GET /registrations/{registrationId}` or the list Category: Registrations Request body: registrationImportType (string) - Discriminates this from an SST or EU OSS registration. Defaults to REGULAR. countryCode (string, required) - ISO 3166-1 alpha-2 country code to register in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code to register in, within `countryCode`. Omit it for a country-level registration. stateName (string) - Display name of the state or province. Omit it and Kintsugi derives it from `countryCode` and `stateCode`. filingFrequency (PublicFilingFrequencyEnum, required) - How often returns should be filed. Send UNKNOWN when the jurisdiction has not assigned one yet; Kintsugi replaces it once it does. allowed values: UNKNOWN, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY, ANNUAL_FISCAL_YEAR, SEMI_MONTHLY, BI_MONTHLY, FOUR_MONTHLY, QUARTERLY_PREPAYMENT registrationDate (string) - Date the registration takes effect in the jurisdiction, as YYYY-MM-DD. Omit it when the jurisdiction has not assigned one. [truncated, see the reference page] --- # Summarize registrations by status GET /registrations/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-registrations-by-status GET /registrations/summary Summarize registrations by status Count registrations by lifecycle status across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to narrow to one. A status with no registrations is omitted rather than reported as zero. Streamlined Sales Tax registrations are excluded, matching the list. Category: Registrations Response fields: total (integer, required) - Total registrations in scope, across every status. Excludes Streamlined Sales Tax registrations, which are not listed on this surface. statusCounts (RegistrationStatusCount[], required) - One entry per status present in scope. A status with no registrations is omitted rather than reported as zero. status (PublicRegistrationStatusEnum, required) - The lifecycle status this count is for. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED count (integer, required) - Number of registrations in scope with this status. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a registration by id GET /registrations/{registration_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-registration-by-id GET /registrations/{registration_id} Get a registration by id Fetch a single tax registration by id. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. organizationName (string) - Display name of the organization the registration belongs to. `null` when the organization has no name set. Sort a list by it with `sort=organizationName`. countryCode (string, required) - ISO 3166-1 alpha-2 country code the registration is held in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code the registration is held in, within `countryCode`. An empty string for a country-level registration. stateName (string) - Display name of the state or province. An empty string for a country-level registration. status (PublicRegistrationStatusEnum, required) - Lifecycle status. Only a REGISTERED or SELF_MANAGED registration has returns filed against it; the others are in progress, wound down, or retained for reporting. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED isPreCollecting (boolean) - True on a PROCESSING registration that marks the organization as collecting tax in the jurisdiction ahead of registration details. Always false on any other status. registrationType (PublicRegistrationTypeEnum, required) - Whether the registration is an EU One Stop Shop scheme covering several member states, or a direct registration with one jurisdiction. allowed values: EU_OSS, OTHER registrationCategory (PublicRegistrationCategoryEnum, required) - How the registration was established: REGULAR for one Kintsugi filed, IMPORTED for one you already held and brought across, DEREGISTRATION for one being wound down. allowed values: REGULAR, IMPORTED, DEREGISTRATION [truncated, see the reference page] --- # Update a registration PATCH /registrations/{registration_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-registration PATCH /registrations/{registration_id} Update a registration Update a registration. This is a partial update: a property you leave out is unchanged, and one you send as `null` is cleared. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. The jurisdiction, the lifecycle status and the sign-in credentials are not editable here: a registration cannot be moved to another jurisdiction, and the other two are separate operations. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Request body: filingFrequency (PublicFilingFrequencyEnum) - How often returns should be filed. Omit to leave unchanged; send a value to replace. allowed values: UNKNOWN, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY, ANNUAL_FISCAL_YEAR, SEMI_MONTHLY, BI_MONTHLY, FOUR_MONTHLY, QUARTERLY_PREPAYMENT registrationDate (string) - Date the registration takes effect in the jurisdiction, as YYYY-MM-DD. Omit to leave unchanged; send `null` to clear. registrationEmail (string) - Email address the jurisdiction has on file. Omit to leave unchanged; send an empty string or `null` to clear it. createFilingsFrom (string) - First period to generate filings for, as YYYY-MM-DD. Omit to leave unchanged; send `null` to clear. registrationRequested (string) - When the registration was submitted to the jurisdiction. Omit to leave unchanged; send `null` to clear. registrationCompleted (string) - When the jurisdiction confirmed the registration. Omit to leave unchanged; send `null` to clear. deregistrationRequested (string) - When deregistration was submitted to the jurisdiction. Omit to leave unchanged; send `null` to clear. deregistrationCompleted (string) - When the jurisdiction confirmed the deregistration. Omit to leave unchanged; send `null` to clear. autoRegistered (boolean) - Whether the registration was completed without manual intervention. Omit to leave unchanged; send `true` or `false` to replace. doNotFile (boolean) - Whether returns are suppressed for this registration. When true, Kintsugi tracks it but does not file against it. Omit to leave unchanged; send `true` or `false` to replace. [truncated, see the reference page] --- # Upload an attachment for a registration POST /registrations/{registration_id}/attachments Source: https://docs.trykintsugi.com/reference/2026-10-06/upload-an-attachment-for-a-registration POST /registrations/{registration_id}/attachments Upload an attachment for a registration Attach a file to a registration in the resolved organization, as `multipart/form-data` with the file in the `file` part. Any file type is accepted, up to 10 MB. Returns the stored attachment's metadata. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, and 413 if the file exceeds the size limit. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: id (string, required) - Kintsugi's unique identifier for the stored attachment. fileName (string, required) - The uploaded file's name. mimeType (string, required) - The uploaded file's MIME type, as sent by the client. fileSizeBytes (integer, required) - The uploaded file's size in bytes. createdAt (string, required) - When the attachment was stored, as an RFC-3339 UTC timestamp. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422 --- # Set a registration's credentials PUT /registrations/{registration_id}/credentials Source: https://docs.trykintsugi.com/reference/2026-10-06/set-a-registration-s-credentials PUT /registrations/{registration_id}/credentials Set a registration's credentials Set the stored sign-in credentials for a registration. Send a value for any of `username`, `password`, `pin`, `securityQuestions`, or `jurisdictionSpecificFields` to set it; a field you leave out (or send as `null`) is left unchanged. Sending `securityQuestions` replaces the stored set. `jurisdictionSpecificFields` accepts California `cdtfaThirdPartyAccessSecurityCode` and Idaho `accessCode` only. Credentials are write-only: this returns the registration, never the values you sent, which are readable only through the credentials reveal endpoint. Only an owner of the organization (or an API key scoped to it) may call it. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access; 403 if your credential may read the organization but is not permitted to change credentials. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Request body: username (string) - Username for the jurisdiction's portal. Omit it or send `null` to leave the stored username unchanged. Write-only: reveal it through the credentials reveal endpoint. password (string) - Password for the jurisdiction's portal, stored encrypted. Omit it or send `null` to leave the stored password unchanged. Write-only: reveal it through the credentials reveal endpoint. pin (string) - PIN for the jurisdiction's portal, where one is used, stored encrypted. Omit it or send `null` to leave the stored PIN unchanged. Write-only: reveal it through the credentials reveal endpoint. securityQuestions (PublicSecurityQuestion[]) - Security questions for the jurisdiction's portal, stored encrypted. Sending this replaces the stored set with the questions you send; omit it or send `null` to leave them unchanged. Write-only: reveal them through the credentials reveal endpoint. question (string, required) - The security question prompt shown by the jurisdiction portal. answer (string, required) - The answer to the security question. Write-only: reveal it through the credentials reveal endpoint. [truncated, see the reference page] --- # Reveal a registration's credentials POST /registrations/{registration_id}/credentials/reveal Source: https://docs.trykintsugi.com/reference/2026-10-06/reveal-a-registration-s-credentials POST /registrations/{registration_id}/credentials/reveal Reveal a registration's credentials Decrypt and return specific stored credentials for a registration. Name the fields to reveal in the request body; each must be one of `username`, `password`, `pin`, `security_questions`, `jurisdictionSpecificFields`. `jurisdictionSpecificFields` returns a map of the registration's decrypted jurisdiction secrets (for example California's CDTFA third-party access code or Idaho's TAP access code), gated to the registration's jurisdiction. A field you do not name, or one with nothing stored, comes back `null`, so the response never confirms which credentials exist beyond what you asked for. This is a privileged, audited operation: only an owner of the organization (or an API key scoped to it) may call it. The response is never cached (`Cache-Control: no-store`). Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists; 403 if your credential may read the organization but is not permitted to reveal credentials. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Request body: fields (PublicRegistrationCredentialField[], required) - Which stored credentials to decrypt and return. Each must be one of `username`, `password`, `pin`, `securityQuestions`, `jurisdictionSpecificFields`; any other value is rejected. A field you do not name comes back `null`, indistinguishable from one with nothing stored. allowed values: username, password, pin, securityQuestions, jurisdictionSpecificFields Response fields: username (string) - Decrypted username, when `username` was requested and one is stored. `null` otherwise. password (string) - Decrypted password, when `password` was requested and one is stored. `null` otherwise. pin (string) - Decrypted PIN, when `pin` was requested and one is stored. `null` otherwise. securityQuestions (PublicSecurityQuestion[]) - Decrypted security questions, when `securityQuestions` was requested and any are stored. `null` otherwise. question (string, required) - The security question prompt shown by the jurisdiction portal. answer (string, required) - The answer to the security question. Write-only: reveal it through the credentials reveal endpoint. [truncated, see the reference page] --- # Deregister a registration POST /registrations/{registration_id}/deregister Source: https://docs.trykintsugi.com/reference/2026-10-06/deregister-a-registration POST /registrations/{registration_id}/deregister Deregister a registration Begin deregistering a registration, moving it into the DEREGISTERING lifecycle status. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. The body must include `closureDate`, `reason`, and `finalReturnAcknowledged`. It may also include `requestId`, a client-minted id for this confirm attempt stored on the audit row. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Returns 409 if the registration is in a lifecycle status it cannot be deregistered from. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration to deregister. Request body: closureDate (string, required) - Effective date the permit closes with the jurisdiction (YYYY-MM-DD). Past and future dates are accepted. Sets the final filing period end. reason (PublicDeregistrationReasonEnum, required) - Why the permit is closing: full business closure, or closing nexus in this one state. allowed values: FULL_BUSINESS_CLOSURE, CLOSING_NEXUS_IN_STATE finalReturnAcknowledged (boolean, required) - Must be true: confirms a final return is still owed for the closing period. requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. organizationName (string) - Display name of the organization the registration belongs to. `null` when the organization has no name set. Sort a list by it with `sort=organizationName`. countryCode (string, required) - ISO 3166-1 alpha-2 country code the registration is held in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code the registration is held in, within `countryCode`. An empty string for a country-level registration. stateName (string) - Display name of the state or province. An empty string for a country-level registration. [truncated, see the reference page] --- # List a registration's OSS countries GET /registrations/{registration_id}/oss-countries Source: https://docs.trykintsugi.com/reference/2026-10-06/list-a-registration-s-oss-countries GET /registrations/{registration_id}/oss-countries List a registration's OSS countries List the EU member states an EU One Stop Shop registration covers. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. A registration that is not an EU OSS scheme returns an empty list. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: ossCountries (RegistrationOssCountry[], required) - EU member states covered by this OSS registration. Empty for a registration that is not an EU OSS scheme. id (string, required) - Kintsugi's unique identifier for this OSS country enrollment. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the EU member state covered, such as `DE`, `FR` or `IT`. effectiveDate (string, required) - Date this member state became covered by the OSS registration, as YYYY-MM-DD. endDate (string) - Date this member state stopped being covered, as YYYY-MM-DD. `null` while the country is still covered. status (PublicOssCountryStatusEnum, required) - Whether the member state is currently covered (ACTIVE) or has been removed from the OSS registration (REMOVED). allowed values: ACTIVE, REMOVED Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Email a registration's password to yourself POST /registrations/{registration_id}/send-password Source: https://docs.trykintsugi.com/reference/2026-10-06/email-a-registration-s-password-to-yourself POST /registrations/{registration_id}/send-password Email a registration's password to yourself Send the registration's stored credentials to the email address on your own credential. Nothing is returned in the body, and the credentials are never exposed to the caller directly. Only an owner of the organization (or an API key scoped to it) may call it. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access; 403 if your credential may read the organization but is not permitted; 400 if the registration has no credentials stored to send. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Start a report job POST /reports/jobs Source: https://docs.trykintsugi.com/reference/2026-10-06/start-a-report-job POST /reports/jobs Start a report job Start generating a report for the resolved organization and return `202` with the job's id. The report is generated asynchronously: poll `GET /reports/jobs/{reportJobId}` for its status, then `GET /reports/jobs/{reportJobId}/download` once it is `READY`. `reportArgs` is shaped by `reportType`; an organization may have at most 5 report jobs queued or processing at once. Set `deliveryMethod` to `EMAIL` to get a download link by email instead of fetching it yourself. A `VAT_REPORT` job is read back as JSON from `GET /reports/jobs/{reportJobId}/result`; it needs VAT accounts payable enabled on the organization (else `403`) and a DE, GB, CZ, ES, or SG filing (else `400`). Category: Reports Request body: deliveryMethod (ReportDeliveryMethodEnum) - `DOWNLOAD` (default) stores the report for `GET /reports/jobs/{reportJobId}/download`. `EMAIL` emails a download link to the address of the user behind your credential; the address cannot be set in the request. Not available for `BULK_FILING_REPORTS` or `VAT_REPORT`. allowed values: DOWNLOAD, EMAIL reportType (string, required) - Which report to generate. reportArgs (NexusReportArgs) - No filters for this report type. Response fields: reportJobId (string, required) - Id of the new report job. status (PublicReportJobStatusEnum) - Always `QUEUED` on creation. allowed values: QUEUED, PROCESSING, READY, FAILED reportType (PublicReportTypeEnum, required) - The report type this job will generate, echoed back from the request. allowed values: NEXUS, TRANSACTIONS_SUMMARY, TRANSACTIONS_DETAILS, FILINGS_SUMMARY, FILINGS, FILING_DETAILS, BULK_FILING_REPORTS, PRODUCTS, COLLECTED_TRANSACTIONS, VAT_REPORT deliveryMethod (ReportDeliveryMethodEnum) - How the report will be delivered, echoed back from the request. allowed values: DOWNLOAD, EMAIL Response statuses: 202, 400, 401, 403, 404, 422, 429, 503 --- # Get a report job's status GET /reports/jobs/{report_job_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-report-job-s-status GET /reports/jobs/{report_job_id} Get a report job's status Get the status of a report job you started. Searched across every organization your credential owns, so no selector is needed for a known id. A job you do not own answers `404`, identical to one that does not exist. Category: Reports Path parameters: report_job_id (string, required) - Id of the report job. Response fields: reportJobId (string, required) - Id of the report job. status (PublicReportJobStatusEnum, required) - Current lifecycle state. Once `READY`, fetch `GET /reports/jobs/{reportJobId}/download` for a download link. allowed values: QUEUED, PROCESSING, READY, FAILED errorMessage (string) - Why the job failed. Null unless status is `FAILED`. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get a report job's download link GET /reports/jobs/{report_job_id}/download Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-report-job-s-download-link GET /reports/jobs/{report_job_id}/download Get a report job's download link Get a presigned download URL for a `READY` report job. Searched across every organization your credential owns. A job you do not own answers `404`, identical to one that does not exist; a job that is not yet `READY` answers `409`. Category: Reports Path parameters: report_job_id (string, required) - Id of the report job. Response fields: url (string, required) - Presigned URL to fetch the report file. expiresInSeconds (integer, required) - How long `url` stays valid, in seconds. filename (string, required) - Suggested filename for the downloaded report. Response statuses: 200, 400, 401, 403, 404, 409, 422, 500 --- # Get a report job's result GET /reports/jobs/{report_job_id}/result Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-report-job-s-result GET /reports/jobs/{report_job_id}/result Get a report job's result Get the JSON result of a `READY` report job whose report is viewed rather than downloaded (today, `VAT_REPORT`). Searched across every organization your credential owns. A job you do not own answers `404`, identical to one that does not exist; a job of a downloadable report type answers `400` (use `GET /reports/jobs/{reportJobId}/download`); a job that is not yet `READY` answers `409`. Category: Reports Path parameters: report_job_id (string, required) - Id of the report job. Response fields: reportJobId (string, required) - Id of the report job. reportType (PublicReportTypeEnum, required) - Which report the job generated. allowed values: NEXUS, TRANSACTIONS_SUMMARY, TRANSACTIONS_DETAILS, FILINGS_SUMMARY, FILINGS, FILING_DETAILS, BULK_FILING_REPORTS, PRODUCTS, COLLECTED_TRANSACTIONS, VAT_REPORT vatReport (VatReport) - The VAT return report. Set when `reportType` is `VAT_REPORT`. filingId (string, required) - Id of the filing the report covers. organizationId (string, required) - Id of the organization that owns it. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing's country, such as `US`, `CA` or `GB`. returnForm (string, required) - Return form the boxes follow. returnFormLabel (string, required) - Display name of the return form. filingEntityRegistrationNumber (string, required) - VAT registration number of the filing entity. Empty if unknown. periodStart (string, required) - First day of the filing period. periodEnd (string, required) - Last day of the filing period. currency (string, required) - ISO-4217 code every amount is in. sections (VatReturnSection[], required) - Return-form sections. sectionLabel (string, required) - Label of the section. boxes (VatReturnBox[], required) - Boxes in this section. boxCode (string, required) - Box number or code on the return form. boxLabel (string, required) - Label of the box on the return form. amount (string, required) - Box amount, in the report currency. category (string, required) - `OUTPUT_VAT`, `INPUT_VAT`, `NET` or `INFORMATIONAL`. sourceTransactionCount (integer, required) - How many transactions contribute to this box. summary (VatReturnSummary, required) - Totals across the return. totalOutputVat (string, required) - VAT charged on sales. [truncated, see the reference page] --- # Estimate tax on a transaction POST /tax-estimations Source: https://docs.trykintsugi.com/reference/2026-10-06/estimate-tax-on-a-transaction POST /tax-estimations Estimate tax on a transaction Estimate the tax due on a transaction without recording it. Nothing is stored and the estimate is not retrievable afterwards, so send the same request again to price it again. The estimate is computed for exactly one organization: send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, which a credential owning more than one organization must do. Each line names either an `externalProductId` you have already created or a `productCategory` and `productSubcategory` pair, which is priced without creating a product. An `externalProductId` is unique only within a connection, so when the same id exists in more than one of your connections, send a `Connection-Id` to price against that connection's product; without one an ambiguous id returns 400. Addresses are validated as part of the estimate: an address that cannot be validated returns 400, one in a country Kintsugi does not cover returns 422, and an address-validation outage returns 503. Tax is only due where an active registration covers the destination, so `hasActiveRegistration` false comes back with every amount at zero. Set `simulateActiveRegistration` to see what the transaction would be taxed at if you were registered there. Category: Tax Estimations Request body: externalId (string, required) - Your identifier for the transaction. Echoed on the response. date (string, required) - When the transaction takes place. Rates in force on this date are the ones applied. currency (string, required) - Currency of every amount on the request, ISO 4217. An unrecognized code returns 400. simulateActiveRegistration (boolean) - Set true to price the transaction as though you were registered in the destination jurisdiction. Use it to preview what registering would cost your buyers; leave it false to see what you owe today. customer (TaxEstimateCustomer) - The buyer. `null` when you have no buyer to attribute the transaction to, in which case no customer-level exemption applies. externalId (string) - Your stable identifier for the buyer. Defaults to an empty string when omitted. When it matches a customer Kintsugi already holds, that customer's exemptions and tax registrations are applied to the estimate. name (string) - Buyer name. companyName (string) - Registered or legal business name. email (string) - Contact email address. [truncated, see the reference page] --- # List transactions GET /transactions Source: https://docs.trykintsugi.com/reference/2026-10-06/list-transactions GET /transactions List transactions List transactions, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Archived and duplicate transactions are never returned. Filter with the query params (`countryCode`, `stateCode`, `dateFrom`, `collectedTax`, `includeRefunds`, `customerId`, and the existing list filters) and sort with `sort` / `order` (default `date` descending, so newest first). A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Transactions Query parameters: sort (PublicTransactionSortEnum) - Field to sort by. Defaults to `date`. allowed values: date, totalAmount, status, country order (PublicTransactionSortOrder) - Sort direction. Defaults to `desc`, so newest first. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. startDate (string) - Include transactions on or after this date (YYYY-MM-DD). endDate (string) - Include transactions on or before this date (YYYY-MM-DD). status (string) - Comma-separated transaction statuses; matches any of them. refundStatus (string) - Comma-separated refund statuses; matches any of them. source (string) - Comma-separated source systems; matches any of them. type (string) - Comma-separated transaction type filters; matches any of them. `CREDIT_NOTE` groups every credit-note type; `SALES_ORDER` filters sales orders. addressStatus (string) - Comma-separated address statuses; matches any of them. connectionId (string) - Comma-separated connection ids; matches any of them. This filters rows by connection. To restrict which organization is read, send the `Connection-Id` header instead. country (string) - Comma-separated ISO-3166 country codes; matches any of them. state (string) - Comma-separated state or province codes; matches any of them. direction (PublicTransactionDirectionEnum) - Restrict to sales or purchases. Omit to return both, matching the unfiltered list. allowed values: SALE, PURCHASE [truncated, see the reference page] --- # Create a transaction POST /transactions Source: https://docs.trykintsugi.com/reference/2026-10-06/create-a-transaction POST /transactions Create a transaction Create a transaction for the resolved organization. Accepted rather than created: tax is calculated asynchronously, so `totalTaxAmountCalculated` and the per-line `taxItems` populate shortly after this returns. `GET /transactions/{id}` can answer `404` for a short time after this returns. Once the transaction can be read, tax may still be calculating (`processingStatus` `QUEUED`); poll for the amounts rather than treating that first `404` as failure. Set `type` to `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE` and send `originalTransactionId` to reverse a pending, committed, or partially refunded sale. The credit note inherits the original transaction's customer, addresses and source; send the line items to credit in `items`, each carrying the `externalId` of the original line. Reversing a transaction you do not own answers `404`, identical to a transaction that does not exist. Re-POSTing the same credit-note external id against the same parent returns the stored credit note (same as a successful create) rather than a conflict. The same external id against a different parent still conflicts. Category: Transactions Request body: externalId (string, required) - Your stable identifier for the transaction. Re-sending the same one updates the existing transaction rather than creating a second. date (string, required) - When the transaction occurred. This drives which filing period it lands in, so send the real transaction time, not the time of the call. type (PublicTransactionTypeEnum) - Kind of transaction. `SALE` records a sale; `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE` with `originalTransactionId` reverses a pending, committed, or partially refunded sale. The stored type is derived from the amount credited, so it can differ from the one you send. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION originalTransactionId (string) - The sale being reversed. It must be pending, committed, or partially refunded. Required when `type` is a credit-note type and must be omitted for a `SALE`. The credit note inherits the original's customer, addresses and source, so send only the lines to credit in `items`. currency (PublicCurrencyEnum, required) - ISO-4217 currency of every amount sent. [truncated, see the reference page] --- # Archive a transaction POST /transactions/archive Source: https://docs.trykintsugi.com/reference/2026-10-06/archive-a-transaction POST /transactions/archive Archive a transaction Archive a transaction for the resolved organization. One-way: an archived transaction is excluded from every read on this API and cannot be restored, and its sales stop counting toward nexus. Archiving a transaction you do not own answers `404`, identical to one that does not exist; a locked or already-filed transaction answers `409`. Category: Transactions Request body: transactionId (string, required) - Id of the transaction to archive. Response fields: id (string, required) - Id of the transaction that was archived. archived (boolean) - Always `true`. Archiving is one-way and cannot be undone. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List transactions with a blank address GET /transactions/blank-addresses Source: https://docs.trykintsugi.com/reference/2026-10-06/list-transactions-with-a-blank-address GET /transactions/blank-addresses List transactions with a blank address List transactions that have no address yet, newest first, keyset-paginated, across every organization you own; narrow with `Organization-Id`, `Connection-Id` or `Entity-Id`. Only committed, non-marketplace transactions dated 2018 or later are listed, the same rows the blank-address count uses. A cursor is only valid for its search and scope. Category: Transactions Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. Response fields: items (Transaction[], required) - The transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID direction (PublicTransactionDirectionEnum, required) - Whether the organization made the sale or made the purchase. Both are returned, so filter on this if you only want one side. allowed values: SALE, PURCHASE customerId (string) - Kintsugi customer this transaction is attributed to. A sale with no customer identity (marketplace, point-of-sale) is attributed to the organization's shared unattributed-sales customer, which reads back with a `null` `externalId`. Check that before treating one `customerId` as one buyer. [truncated, see the reference page] --- # Export a transaction report POST /transactions/export Source: https://docs.trykintsugi.com/reference/2026-10-06/export-a-transaction-report POST /transactions/export Export a transaction report Kick off an asynchronous transaction report for the resolved organization and return `202` with the export's id. `SUMMARY` is aggregated figures; `DETAILS` is one row per transaction; `COLLECTED` is imported-tax sales in a jurisdiction. `deliveryMethod` chooses how you get it: `EMAIL` emails it to `email` when ready (a bearer session may omit `email` and use the signed-in user); `DOWNLOAD` stores it and you poll `GET /transactions/exports/{exportId}` for a presigned link (so `email` must be omitted). An `EMAIL` export for an organization that has disabled email delivery answers `400`. Category: Transactions Request body: deliveryMethod (TransactionExportDelivery, required) - How to deliver the report. `EMAIL` emails it to `email` when ready; `DOWNLOAD` stores it and you poll `GET /transactions/exports/{exportId}` for a presigned link. allowed values: EMAIL, DOWNLOAD reportType (TransactionReportType, required) - Which report to generate. `SUMMARY` is aggregated figures; `DETAILS` is one row per transaction; `COLLECTED` is imported-tax sales in a jurisdiction (the collected-tax drawer). allowed values: SUMMARY, DETAILS, COLLECTED email (string) - Email address the report is delivered to. Required when `deliveryMethod` is `EMAIL` unless the caller is a bearer session (which defaults to the signed-in user). Must be omitted when `deliveryMethod` is `DOWNLOAD`. countryCode (string) - Restrict the report to this ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Required when `reportType` is `COLLECTED`. stateCode (string) - Restrict the report to this state or province code. When `reportType` is `COLLECTED`, `FD` (federal nexus sentinel) is not applied as a state filter. startDate (string) - Include transactions on or after this date (YYYY-MM-DD). endDate (string) - Include transactions on or before this date (YYYY-MM-DD). Applies to `SUMMARY`, `DETAILS`, and `COLLECTED`. includeInvalidAddresses (boolean) - Include transactions with invalid addresses. Applies to the `DETAILS` report only; ignored for `SUMMARY` and `COLLECTED`. includeRefunds (boolean) - When `reportType` is `COLLECTED`, include credit notes with nonzero imported tax. Ignored for `SUMMARY` and `DETAILS`. Response fields: [truncated, see the reference page] --- # Get an export's status GET /transactions/exports/{export_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-an-export-s-status GET /transactions/exports/{export_id} Get an export's status Get the status of an export you started, and, once a `DOWNLOAD` export is `READY`, a presigned `downloadUrl` to fetch it. `downloadUrl` is `null` while the export is in progress and for an `EMAIL` export, which is delivered by email instead. Searched across every organization your credential owns; an export you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: export_id (string, required) - The id of the export job. Response fields: exportId (string, required) - Id of the export job. status (TransactionExportStatus, required) - Lifecycle state. `QUEUED` and `PROCESSING` are in progress; `READY` is done; `FAILED` could not be generated. allowed values: QUEUED, PROCESSING, READY, FAILED deliveryMethod (TransactionExportDelivery, required) - How the report is delivered. allowed values: EMAIL, DOWNLOAD downloadUrl (string) - Presigned URL to download the report. Non-`null` only when `status` is `READY` and `deliveryMethod` is `DOWNLOAD`; `null` otherwise, including for an `EMAIL` export, which is delivered by email rather than here. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List a filing's transactions GET /transactions/filings/{filing_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/list-a-filing-s-transactions GET /transactions/filings/{filing_id} List a filing's transactions List the transactions assigned to a filing, keyset-paginated the same way as `GET /transactions`. Covers every organization your credential owns. A filing id you do not own, or that does not exist, reads as an empty page rather than `404`, matching an owned filing with no transactions. Category: Transactions Path parameters: filing_id (string, required) - Id of the filing whose transactions to list. Query parameters: sort (PublicTransactionSortEnum) - Field to sort by. Defaults to `date`. allowed values: date, totalAmount, status, country order (PublicTransactionSortOrder) - Sort direction. Defaults to `desc`, so newest first. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Transaction[], required) - The transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID direction (PublicTransactionDirectionEnum, required) - Whether the organization made the sale or made the purchase. Both are returned, so filter on this if you only want one side. allowed values: SALE, PURCHASE [truncated, see the reference page] --- # List transactions with an invalid address GET /transactions/invalid-addresses Source: https://docs.trykintsugi.com/reference/2026-10-06/list-transactions-with-an-invalid-address GET /transactions/invalid-addresses List transactions with an invalid address List transactions that need an address fix, keyset-paginated, across every organization you own; narrow with `Organization-Id`, `Connection-Id` or `Entity-Id`. Includes transactions marked invalid and verified ones whose US or unknown-country ship-to address is still invalid. A cursor is only valid for its sort, filters and scope. Category: Transactions Query parameters: sort (PublicInvalidAddressSortEnum) - `usFirst` (default) lists US addresses first, then other countries in country order, then rows with no country. `countryAsc` and `countryDesc` order by country, with no-country rows last. Newest first breaks ties. allowed values: usFirst, countryAsc, countryDesc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. country (string) - ISO-3166 country code of the invalid address. hasCountry (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a country. hasState (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a state. hasCity (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a city. hasCounty (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a county. hasPostalCode (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a postal code. addressNotEmpty (boolean) - `true` keeps addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: items (Transaction[], required) - The transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. [truncated, see the reference page] --- # Get connections' transaction date ranges GET /transactions/min-max-date Source: https://docs.trykintsugi.com/reference/2026-10-06/get-connections-transaction-date-ranges GET /transactions/min-max-date Get connections' transaction date ranges Get the earliest and latest non-archived, non-duplicate transaction date for each requested connection. Covers every organization your credential owns; a connection id you do not own, or that does not exist, reads `null`/`null` rather than being omitted or answering `404`, so it cannot be probed. Category: Transactions Query parameters: connectionIds (string, required) - Comma-separated connection ids to get date ranges for. Response fields: items (ConnectionDateRange[], required) - One entry per requested `connectionId`, in the order requested. A connection id you do not own, or with no matching transactions, reads `null`/`null` rather than being omitted. connectionId (string, required) - Id of the connection. minDate (string) - Earliest non-archived, non-duplicate transaction date for this connection, or `null` when it has none. maxDate (string) - Latest non-archived, non-duplicate transaction date for this connection, or `null` when it has none. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List transaction sources GET /transactions/sources Source: https://docs.trykintsugi.com/reference/2026-10-06/list-transaction-sources GET /transactions/sources List transaction sources List the distinct `source` values in use across your transactions. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Useful for a `source` filter dropdown of values that actually occur. Category: Transactions Response fields: items (TransactionSource[]) - Sources in use; empty when the scope has no transactions. value (string, required) - The `source` value, usable in the `source` list filter. label (string, required) - Human-readable display label for `value` (for example `Shopify`). Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Summarize transactions GET /transactions/summary Source: https://docs.trykintsugi.com/reference/2026-10-06/summarize-transactions GET /transactions/summary Summarize transactions Aggregate counts and money totals over your transactions. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Accepts the same filters as `GET /transactions`, so the totals reflect the filtered set. Archived and duplicate transactions are excluded, and the money totals are sales only, matching the list. `incompleteAddressCount` is deliberately independent of the filters: it always counts every in-scope transaction whose address cannot be resolved. Category: Transactions Query parameters: search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. startDate (string) - Include transactions on or after this date (YYYY-MM-DD). endDate (string) - Include transactions on or before this date (YYYY-MM-DD). status (string) - Comma-separated transaction statuses; matches any of them. refundStatus (string) - Comma-separated refund statuses; matches any of them. source (string) - Comma-separated source systems; matches any of them. type (string) - Comma-separated transaction type filters; matches any of them. `CREDIT_NOTE` groups every credit-note type; `SALES_ORDER` filters sales orders. addressStatus (string) - Comma-separated address statuses; matches any of them. connectionId (string) - Comma-separated connection ids; matches any of them. This filters rows by connection. To restrict which organization is read, send the `Connection-Id` header instead. country (string) - Comma-separated ISO-3166 country codes; matches any of them. state (string) - Comma-separated state or province codes; matches any of them. direction (PublicTransactionDirectionEnum) - Restrict to sales or purchases. Omit to return both, matching the unfiltered list. allowed values: SALE, PURCHASE marketplace (boolean) - Restrict to marketplace (true) or non-marketplace (false) rows. filingId (string) - Restrict to transactions assigned to this filing. customerId (string) - Restrict to one customer's transactions by customer id. A customer outside your organizations returns an empty page. exempt (string) - Comma-separated exemption statuses; matches any of them. processingStatus (string) - Comma-separated processing statuses; matches any of them. [truncated, see the reference page] --- # Get a transaction by id GET /transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-transaction-by-id GET /transactions/{transaction_id} Get a transaction by id Fetch a single transaction by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction. Response fields: id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID direction (PublicTransactionDirectionEnum, required) - Whether the organization made the sale or made the purchase. Both are returned, so filter on this if you only want one side. allowed values: SALE, PURCHASE customerId (string) - Kintsugi customer this transaction is attributed to. A sale with no customer identity (marketplace, point-of-sale) is attributed to the organization's shared unattributed-sales customer, which reads back with a `null` `externalId`. Check that before treating one `customerId` as one buyer. customerName (string) - Name of the customer this transaction is attributed to, or `null` when it has no customer or the customer has no name. customerExternalId (string) - Your identifier for the customer this transaction is attributed to, or `null` when it has no customer or the customer has no external id. connectionId (string) - Connection that synced this transaction, if any. source (string, required) - Origin system of the transaction. Sources outside the public set are reported as OTHER. [truncated, see the reference page] --- # Update a transaction PUT /transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-transaction PUT /transactions/{transaction_id} Update a transaction Replace a transaction's fields. The scalar fields (`date`, `totalAmount`, `description`, `currency`, `source`, `marketplace`) and the customer are overwritten with what you send. Line items are replaced: an item is matched to a stored one by `externalId`, a new `externalId` is added, and a stored line whose `externalId` you do not send is removed. Addresses are replaced per `type`: send a `SHIP_TO` to replace the ship-to, a `BILL_TO` to replace the bill-to; a type you omit is left as it was. The transaction's `type` is preserved and cannot be changed here. Tax is recalculated asynchronously, so `totalTaxAmountCalculated` and the per-line `taxItems` repopulate shortly after this returns. Updating a transaction you do not own answers `404`, identical to one that does not exist. A locked or already-filed transaction answers `409`. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to update. Request body: externalId (string, required) - Your stable identifier for the transaction. date (string, required) - When the transaction occurred. This drives which filing period it lands in, so send the real transaction time, not the time of the call. currency (PublicCurrencyEnum, required) - ISO-4217 currency of every amount sent. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) totalAmount (string) - Total transaction amount. addresses (TransactionAddressWrite[]) - Addresses for the transaction, replaced per `type`: a `SHIP_TO` you send replaces the stored ship-to, a `BILL_TO` the stored bill-to, and a type you omit is left unchanged. Jurisdiction is resolved from these, so an incomplete address means tax cannot be calculated accurately. type (PublicAddressTypeEnum, required) - Which party or location this address represents. Tax jurisdiction usually follows `SHIP_TO` (or `BILL_TO` when there is no ship-to). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM street1 (string) - First line of the street address. Omit or send `null` when unset. street2 (string) - Second line of the street address. Omit or send `null` when unset. city (string) - City or locality. Omit or send `null` when unset. county (string) - County or district. Omit or send `null` when unset. [truncated, see the reference page] --- # Update a credit note PATCH /transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-credit-note PATCH /transactions/{transaction_id} Update a credit note Update an existing credit note (a transaction whose `type` is `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE`). A true partial update: every field — `externalId`, `date`, `totalAmount`, `currency`, `description`, `marketplace`, `status` and `items` — is optional, and one you omit keeps the credit note's current stored value rather than being reset to a default. Send `status` as `CANCELLED` to reverse the credit note without deleting it; omitted, it stays whatever it already is (it does NOT default to `COMMITTED`). Calling this on a transaction that is not a credit note answers `400`; on one already `CANCELLED` also answers `400`. A locked or already-filed credit note answers `409`. Updating a credit note you do not own answers `404`, identical to one that does not exist. `PUT /transactions/{transactionId}` amends an ordinary transaction; it does not accept a credit note. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the credit note to update. Request body: externalId (string) - Your stable identifier for the credit note. Omit to keep the stored one. date (string) - When the credit note was issued. Omit to keep the stored date. status (string) - Lifecycle state of the credit note. Send `CANCELLED` to reverse it without deleting it; amounts and lines are otherwise unaffected. Omit to keep the current status — it does NOT default to `COMMITTED`. allowed values: PENDING, COMMITTED, CANCELLED currency (PublicCurrencyEnum) - ISO-4217 currency of every amount sent. Omit to keep the stored currency. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) totalAmount (string) - Total credit note amount. Omit to keep the stored amount — there is no default of `0.00`. description (string) - Free-text description of the credit note. Omit to keep the stored description. marketplace (boolean) - True for a marketplace or reseller credit note. Omit to keep the credit note's current marketplace flag. items (TransactionItemWrite[]) - Lines to credit. Each must carry the `externalId` of the original sale's line it reverses, exactly like the credit-note create. Omit to keep the credit note's stored lines. externalProductId (string, required) - Your identifier for the product on this line. [truncated, see the reference page] --- # Update a transaction's addresses PATCH /transactions/{transaction_id}/addresses Source: https://docs.trykintsugi.com/reference/2026-10-06/update-a-transaction-s-addresses PATCH /transactions/{transaction_id}/addresses Update a transaction's addresses Edit one or more of a transaction's addresses without touching its line items. Each address is upserted by its `type` (or `id`); a type you omit is left unchanged. Editing an address resets its validation, so `addressStatus` returns to `UNVERIFIED` and the address is re-verified on the next processing pass. Returns the updated transaction. Editing a transaction you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to edit. Request body: addresses (TransactionAddressEdit[], required) - Addresses to update on the transaction. Each is upserted by `type` (or `id`); a type you omit is left unchanged, and line items are never touched. Editing an address resets its validation, so it is re-verified on the next processing pass. type (PublicAddressTypeEnum, required) - Which address on the transaction to edit (its role). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM id (string) - Id of the address to edit. Omit to target the transaction's address of this `type`, creating one if it has none. street1 (string) - First line of the street address. Omit or send `null` to clear; send a value to set. street2 (string) - Second line of the street address. Omit or send `null` to clear; send a value to set. city (string) - City or locality. Omit or send `null` to clear; send a value to set. county (string) - County or district. Omit or send `null` to clear; send a value to set. state (string) - State or province code. Omit or send `null` to clear; send a value to set. postalCode (string) - Postal or ZIP code. Omit or send `null` to clear; send a value to set. countryCode (string) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Omit or send `null` to clear; send a value to set. fullAddress (string) - Single-line full address. Omit or send `null` to clear; send a value to set. phone (string) - Contact phone for the address. Omit or send `null` to clear; send a value to set. isUnincorporated (boolean) - When `true`, city-level tax rates are not applied to this address. Omit or send `null` to leave the stored value unchanged; send `false` to clear it. Response fields: [truncated, see the reference page] --- # Get a transaction's backlink GET /transactions/{transaction_id}/backlink Source: https://docs.trykintsugi.com/reference/2026-10-06/get-a-transaction-s-backlink GET /transactions/{transaction_id}/backlink Get a transaction's backlink Get a deep link to a transaction in its source system (for example NetSuite). Searched across every organization your credential owns. Answers `404` when not owned, and also when a backlink cannot be built (an unsupported source, no connection), so the two cannot be told apart. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction. Response fields: transactionId (string, required) - Id of the transaction. backlink (string, required) - URL to the transaction in the source system. connectionId (string, required) - Id of the connection the transaction was imported through. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List related transactions GET /transactions/{transaction_id}/related Source: https://docs.trykintsugi.com/reference/2026-10-06/list-related-transactions GET /transactions/{transaction_id}/related List related transactions List the transactions related to one: the credit notes that reverse a sale, or the original sale a credit note reverses. Searched across every organization your credential owns, so no selector is needed for a known id. A transaction you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction. Response fields: items (RelatedTransaction[]) - Transactions related to the requested one; empty when there are none. id (string, required) - Kintsugi's unique identifier for the transaction. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. customerName (string) - Name of the customer the transaction is attributed to, if any. description (string) - Transaction description; an empty string when the source sent none. date (string, required) - When the transaction occurred. shopDate (string) - Calendar day the transaction occurred in the shop's timezone (`YYYY-MM-DD`), or `null` when the source did not report one. state (string) - Resolved state or province code, or `null` when none was resolved. countryCode (string) - Resolved ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`, or `null` when none was resolved. status (PublicTransactionStatusEnum, required) - Lifecycle status of the transaction. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID totalAmount (string, required) - Total transaction amount. totalTaxAmountCalculated (string, required) - Total tax Kintsugi calculated. currency (PublicCurrencyEnum, required) - ISO-4217 currency the unconverted amounts are in. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) destinationCurrency (PublicCurrencyEnum) - Currency the converted amounts are in, or `null` when unconverted. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) convertedTotalAmount (string) - `totalAmount` in the destination currency, or `null` when unconverted. [truncated, see the reference page] --- # Mark or unmark a transaction as tax-only PATCH /transactions/{transaction_id}/tax-only Source: https://docs.trykintsugi.com/reference/2026-10-06/mark-or-unmark-a-transaction-as-tax-only PATCH /transactions/{transaction_id}/tax-only Mark or unmark a transaction as tax-only Reclassify a transaction as tax-only, or restore it. Set `taxOnly` to `true` to mark it: a `SALE` becomes `TAX_COLLECTION` and a credit note becomes `TAX_REFUND`. Set it to `false` to unmark: a `TAX_COLLECTION` restores to `SALE`, and a `TAX_REFUND` re-derives `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE` from the amounts. Only `type` changes; every amount is preserved. Marking a type that is already tax-only, or unmarking one that is not, is a no-op that returns the transaction unchanged. A type this cannot apply to, or a locked or already-filed transaction, answers `409`. Updating a transaction you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to reclassify. Request body: taxOnly (boolean, required) - True to mark the transaction tax-only (a `SALE` becomes `TAX_COLLECTION`; a credit note becomes `TAX_REFUND`). False to unmark it, restoring `SALE` or re-deriving `FULL_CREDIT_NOTE` / `PARTIAL_CREDIT_NOTE`. Only `type` is affected; every amount is preserved. Response fields: id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID [truncated, see the reference page] --- # List organization users GET /users Source: https://docs.trykintsugi.com/reference/2026-10-06/list-organization-users GET /users List organization users List the people attached to one organization: its members, plus anyone who has been invited and has not accepted yet (`status` `PENDING`). Rows are ordered by email. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`; omit `Organization-Id` when the bearer is an Owner or Admin of exactly one portfolio to list the partner firm team instead. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Category: Users Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (OrgUser[], required) - Users on this page, ordered by email. id (string, required) - Opaque unique identifier of the user. Treat as opaque; do not parse. For a `PENDING` row this is the invitation's identifier, which the remove endpoint accepts to revoke the invitation. organizationId (string, required) - Owning organization id (`orgn_…`), or the partner portfolio id (`part_…`) when the row is on the firm team. email (string, required) - User's email address. role (PublicUserRoleEnum, required) - Member's role in the organization, or null if the underlying role is not one of the published values. allowed values: OWNER, ADMIN, MEMBER status (PublicUserStatusEnum, required) - Membership status of the user in the organization. `INACTIVE` means the user cannot sign in and keeps their role until reactivated. `PENDING` means they have been invited and have not accepted yet, so they are not a member and have no name on file. allowed values: ACTIVE, INACTIVE, PENDING firstName (string, required) - User's first name. Empty string if unset. lastName (string, required) - User's last name. Empty string if unset. createdAt (string, required) - When the user account was created, or for a `PENDING` row when the invitation was sent. Null if unknown. nextCursor (string) - Opaque cursor for the next page, or null on the last page. Echo it as the request `cursor` to page forward. Pages are not a stable snapshot: if the roster changes while you walk it, a user can shift across a page boundary and be seen twice or missed. [truncated, see the reference page] --- # List pending organization invitations GET /users/invites Source: https://docs.trykintsugi.com/reference/2026-10-06/list-pending-organization-invitations GET /users/invites List pending organization invitations List the pending (not yet accepted) invitations for one organization. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`; omit it when the bearer is an Owner or Admin of exactly one portfolio to list firm invitations instead. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Applies to organizations using Kintsugi-managed sign-in; an organization federated to its own identity provider manages invitations there. Category: Users Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (OrgInvite[], required) - Pending invitations on this page. id (string, required) - Opaque unique identifier of the invitation. Treat as opaque; do not parse. Pass it to the revoke endpoint to cancel the invitation. organizationId (string, required) - Owning organization id (`orgn_…`), or the partner portfolio id (`part_…`) when the invitation is for the firm team. email (string, required) - Email address the invitation was sent to. role (PublicUserRoleEnum, required) - Role the invitee will hold once they accept, or null if the underlying role is not one of the published values. allowed values: OWNER, ADMIN, MEMBER status (PublicUserStatusEnum, required) - Always `PENDING`: the invitation has been sent but not yet accepted. allowed values: ACTIVE, INACTIVE, PENDING createdAt (string, required) - When the invitation was created, or null if unknown. expiresAt (string, required) - When the invitation expires, or null if unknown. nextCursor (string) - Opaque cursor for the next page, or null on the last page. Echo it as the request `cursor` to page forward. Pages are not a stable snapshot: if the pending invitations change while you walk them, one can shift across a page boundary and be seen twice or missed. previousCursor (string) - Always null: this list pages forward only over the provider's paging. hasMore (boolean) - Whether a next page exists. hasPrevious (boolean) - Always false: this list pages forward only. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Invite a user to an organization POST /users/invites Source: https://docs.trykintsugi.com/reference/2026-10-06/invite-a-user-to-an-organization POST /users/invites Invite a user to an organization Invite a user to the organization by email. If the email already belongs to a Kintsugi user, they are added to the organization directly and the response `outcome` is `ADDED` with the new `user`; otherwise an invitation is sent and `outcome` is `INVITED` with the pending `invite`. Idempotent on the email: if they are already a member, or already have an invitation outstanding, the existing one is returned unchanged with a `200` instead of `201`, and their role is not modified. Use `PATCH /users/{userId}` to change a role. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. Only an Owner can assign the Owner role (403). Applies to organizations using Kintsugi-managed sign-in; an organization federated to its own identity provider manages invitations there. Category: Users Request body: email (string, required) - Email address of the user to invite or add to the organization. role (PublicUserRoleEnum, required) - Primary role to grant the user in the organization. allowed values: OWNER, ADMIN, MEMBER additionalRoles (string[]) - Optional additional role names to assign alongside the primary role. Response fields: outcome (PublicInviteOutcomeEnum, required) - `INVITED` when the result is an invitation, `ADDED` when an existing user holds membership directly. Branch on this rather than on which of `invite` / `user` is populated. Whether it was newly created is the response status: `201` created, `200` already existed. allowed values: INVITED, ADDED invite (OrgInvite, required) - The invitation when `outcome` is `INVITED`; null otherwise. id (string, required) - Opaque unique identifier of the invitation. Treat as opaque; do not parse. Pass it to the revoke endpoint to cancel the invitation. organizationId (string, required) - Owning organization id (`orgn_…`), or the partner portfolio id (`part_…`) when the invitation is for the firm team. email (string, required) - Email address the invitation was sent to. role (PublicUserRoleEnum, required) - Role the invitee will hold once they accept, or null if the underlying role is not one of the published values. allowed values: OWNER, ADMIN, MEMBER [truncated, see the reference page] --- # Revoke a pending organization invitation DELETE /users/invites/{invite_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/revoke-a-pending-organization-invitation DELETE /users/invites/{invite_id} Revoke a pending organization invitation Revoke a pending invitation by its opaque id. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. Returns 404 if the organization is not accessible or no such pending invitation exists; the response is empty on success. Applies to organizations using Kintsugi-managed sign-in; an organization federated to its own identity provider manages invitations there. Category: Users Path parameters: invite_id (string, required) - Opaque identifier of the invitation to revoke. Treat as opaque. Response statuses: 204, 400, 401, 403, 404, 422, 503 --- # Update an organization user's role PATCH /users/{user_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/update-an-organization-user-s-role PATCH /users/{user_id} Update an organization user's role Change a member's role in the organization (optionally replacing their additional roles). Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. You cannot change your own membership, only an Owner can change another Owner, and only an Owner can assign the Owner role; each returns 403. A `PENDING` user has no role to change and returns 409: revoke their invitation and send a new one. Returns 404 if the organization is not accessible; the response is empty on success. Category: Users Path parameters: user_id (string, required) - Opaque identifier of the user to update. Treat as opaque. Request body: role (PublicUserRoleEnum, required) - New primary role for the user in the organization. allowed values: OWNER, ADMIN, MEMBER additionalRoles (string[]) - Optional additional role names to assign alongside the primary role. When provided, replaces the user's current additional roles; omit the field to leave them unchanged, or send an empty list to clear them. Response statuses: 204, 400, 401, 403, 404, 409, 422, 503 --- # Remove a user from an organization DELETE /users/{user_id} Source: https://docs.trykintsugi.com/reference/2026-10-06/remove-a-user-from-an-organization DELETE /users/{user_id} Remove a user from an organization Remove a member from the organization. If the id is a `PENDING` user, their invitation is revoked instead. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. You cannot remove yourself, and only an Owner can remove another Owner; either returns 403. Returns 404 if the organization is not accessible, or no such user or invitation exists; the response is empty on success. Category: Users Path parameters: user_id (string, required) - Opaque identifier of the user to remove. Treat as opaque. Response statuses: 204, 400, 401, 403, 404, 422, 503 --- # Preview addresses eligible for batch approval GET /addresses/approval-preview Source: https://docs.trykintsugi.com/reference/2026-07-21/preview-addresses-eligible-for-batch-approval GET /addresses/approval-preview Preview addresses eligible for batch approval Preview the addresses a batch approval would cover across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `status` (comma-separated, default `INVALID,BLANK`) chooses which statuses are eligible, and `limit` caps the returned `addresses` page; `totalEligible` is the full count regardless of `limit`. The same `country`, `has*` and `addressNotEmpty` filters as the summary apply. Category: Addresses Query parameters: status (string) - Comma-separated address statuses to treat as eligible; defaults to `INVALID,BLANK`. limit (integer) - Maximum number of addresses to return in the preview page. country (string) - ISO-3166 alpha-2 country code to filter by. hasCountry (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a country. hasState (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a state. hasCity (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a city. hasCounty (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a county. hasPostalCode (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a postal code. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: totalEligible (integer, required) - Total addresses eligible for approval under the requested filters. addresses (TransactionAddress[], required) - First page of eligible addresses, capped by `limit`. `totalEligible` is the full count regardless of this cap. id (string, required) - Identifier for the address. type (PublicAddressTypeEnum, required) - Which party or location this address represents. Tax jurisdiction usually follows `SHIP_TO` (or `BILL_TO` when there is no ship-to). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. [truncated, see the reference page] --- # Batch-approve addresses POST /addresses/approve Source: https://docs.trykintsugi.com/reference/2026-07-21/batch-approve-addresses POST /addresses/approve Batch-approve addresses Mark a set of addresses verified and requeue their transactions for tax recalculation, for one organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to name it. Choose the set with `addressIds` OR `filters`, exactly one. `status` limits which verification statuses are eligible (default `INVALID,BLANK`) and `limit` caps how many are approved. An already-verified address is skipped, not re-approved. Any member of the organization, a partner Owner/Admin or an API key for the organization may approve. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Request body: addressIds (string[]) - Ids of the addresses to approve. Send this or `filters`, not both. `null` when selecting by `filters` instead. filters (AddressApproveFilters) - Filter selecting the addresses to approve. Send this or `addressIds`, not both. `null` when selecting by `addressIds` instead. hasCountry (boolean) - Keep addresses that do (`true`) or do not (`false`) have a country. Omit to not filter on this. hasState (boolean) - Keep addresses that do (`true`) or do not (`false`) have a state. Omit to not filter on this. hasCity (boolean) - Keep addresses that do (`true`) or do not (`false`) have a city. Omit to not filter on this. hasCounty (boolean) - Keep addresses that do (`true`) or do not (`false`) have a county. Omit to not filter on this. hasPostalCode (boolean) - Keep addresses that do (`true`) or do not (`false`) have a postal code. Omit to not filter on this. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. country (string) - ISO-3166 alpha-2 country code to filter by. Omit to not filter by country. status (ApprovableAddressStatus[]) - Verification statuses eligible for approval; an address outside this set is skipped. Only `INVALID` and `BLANK` may be approved, and both are the default. allowed values: INVALID, BLANK limit (integer) - Maximum number of addresses to approve in this request. Response fields: approvedCount (integer, required) - Number of addresses this request marked verified. skippedCount (integer, required) - Number of selected addresses left unchanged because they were already verified. [truncated, see the reference page] --- # Suggest a fill for one blank address GET /addresses/blank-suggestion Source: https://docs.trykintsugi.com/reference/2026-07-21/suggest-a-fill-for-one-blank-address GET /addresses/blank-suggestion Suggest a fill for one blank address Suggest a postal code, city, state and country for one blank address, chosen from the organization's most common verified address. A preview only: apply it with `PATCH /transactions/{transactionId}/addresses`. Searched across every organization your credential owns. Returns 400 if the address already has a postal code, city and state, and 404 if the address does not exist, is not owned, or no valid address exists to suggest from. Category: Addresses Query parameters: addressId (string, required) - The blank address to suggest a fill for. Response fields: addressId (string, required) - The blank address this suggestion is for. city (string) - City or locality. An empty string when none was supplied. state (string) - Suggested state or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. country (string) - Suggested ISO-3166 alpha-2 country code. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Assign the business address to blank transactions POST /addresses/bulk-assign-business-address Source: https://docs.trykintsugi.com/reference/2026-07-21/assign-the-business-address-to-blank-transactions POST /addresses/bulk-assign-business-address Assign the business address to blank transactions Assign the organization's own business address to its selected blank-address transactions and re-queue validation. Ids that are not (or no longer) blank-eligible are ignored and reported. `certified` must be `true`. Returns `businessAddressMissing: true` (assigning nothing) when the organization has no business address configured. Any member of the organization, a partner Owner/Admin or an API key for the organization may assign. A partner Member gets 403, you get 404 if you do not own the organization, and 400 if `certified` is not set. Category: Addresses Request body: transactionIds (string[], required) - Ids of the blank-address transactions to assign the business address to. certified (boolean) - Must be `true` to certify the assignment; the request is rejected otherwise. Response fields: updated (integer, required) - Transactions the business address was assigned to. skippedNoBusinessAddress (integer, required) - Eligible transactions skipped because the organization has no business address configured. failed (integer, required) - Transactions whose address write failed. ignored (integer, required) - Requested transactions dropped because they were not (or no longer) blank-eligible. businessAddressMissing (boolean, required) - `true` when the organization has no business address configured, so nothing was assigned. Set one and retry. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Fill the organization's blank-address transactions POST /addresses/fill-blank Source: https://docs.trykintsugi.com/reference/2026-07-21/fill-the-organization-s-blank-address-transactions POST /addresses/fill-blank Fill the organization's blank-address transactions Queue a fill for every blank-address transaction in the resolved organization, assigning each a most-likely address inferred from the organization's own verified addresses, and re-queue it for tax recalculation. `queued` is `false` when the organization has no blank-address transactions to fill. Any member of the organization, a partner Owner/Admin or an API key for the organization may run it. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Response fields: queued (boolean, required) - Whether a fill job was queued. `false` when the organization had no blank-address transactions to fill. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Count addresses needing attention GET /addresses/needs-attention-summary Source: https://docs.trykintsugi.com/reference/2026-07-21/count-addresses-needing-attention GET /addresses/needs-attention-summary Count addresses needing attention Count the addresses needing attention (invalid and blank) across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. These match the review dashboard, which counts committed transactions with an address problem rather than raw address rows, so they can differ from `byStatus` on the summary. Category: Addresses Response fields: invalid (integer, required) - Transactions in scope with an invalid address. blank (integer, required) - Transactions in scope with a blank address. needsAttentionTotal (integer, required) - Sum of `invalid` and `blank`. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Re-queue invalid-address transactions for validation PUT /addresses/revalidation Source: https://docs.trykintsugi.com/reference/2026-07-21/re-queue-invalid-address-transactions-for-validation PUT /addresses/revalidation Re-queue invalid-address transactions for validation Re-queue the invalid-address transactions matching the given filters (the same `country`/`countryIn`, `has*`, `addressNotEmpty` and `searchQuery` filters as the review list) in one organization for address validation, returning how many were re-queued. Any member of the organization, a partner Owner/Admin or an API key for the organization may run it. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Query parameters: searchQuery (string) - Free-text search over the invalid-address transactions to re-queue. countryIn (string) - Comma-separated ISO-3166 alpha-2 country codes to filter by; the `EU` placeholder expands to the EU member states. Overrides `country`. country (string) - ISO-3166 alpha-2 country code to filter by. hasCountry (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a country. hasState (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a state. hasCity (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a city. hasCounty (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a county. hasPostalCode (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a postal code. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: revalidatedCount (integer, required) - Number of invalid-address transactions re-queued for validation. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Suggest addresses for a partial input POST /addresses/suggestions Source: https://docs.trykintsugi.com/reference/2026-07-21/suggest-addresses-for-a-partial-input POST /addresses/suggestions Suggest addresses for a partial input Return a list of suggested addresses that match a partial or ambiguous input, to power address autocomplete. The list is empty when there are no matches. Returns 400 if the country is not supported, and 503 if the address validation service is temporarily unavailable. Category: Addresses Request body: street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. fullAddress (string) - Single-line full address, as an alternative to fields. country (string) - ISO-3166 alpha-2 country code. Response fields: city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province of the suggested address. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. country (string) - ISO-3166 alpha-2 country code of the suggestion. Response statuses: 200, 400, 401, 403, 404, 409, 422, 503 --- # Suggest addresses for many inputs POST /addresses/suggestions/bulk Source: https://docs.trykintsugi.com/reference/2026-07-21/suggest-addresses-for-many-inputs POST /addresses/suggestions/bulk Suggest addresses for many inputs Return suggestions for a batch of addresses in one request, one group per input correlated by the `id` you send. Every input always comes back as a group, in request order; a group has an empty `suggestions` list when there are no matches, the country is unsupported, or the validation service was unavailable for it. Category: Addresses Request body: addresses (BulkAddressSuggestionsItem[], required) - The addresses to fetch suggestions for. id (string) - Your identifier, echoed on the response group. connectionId (string) - Connection this address belongs to, used to resolve a default country. street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. fullAddress (string) - Single-line full address, as an alternative to fields. country (string) - ISO-3166 alpha-2 country code. Response fields: id (string) - The `id` from the matching request address; empty if none was sent. suggestions (AddressSuggestion[], required) - Suggested addresses for this input; empty when there are none. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province of the suggested address. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. country (string) - ISO-3166 alpha-2 country code of the suggestion. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Summarize addresses by verification status GET /addresses/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-addresses-by-verification-status GET /addresses/summary Summarize addresses by verification status Count addresses by verification status across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Filter the counted set with `country`, the `has*` presence filters and `addressNotEmpty`, and with `addressType`. `total` is the sum of `byStatus`. Category: Addresses Query parameters: addressType (PublicAddressTypeEnum) - Address role to filter by (e.g. `SHIP_TO`). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM country (string) - ISO-3166 alpha-2 country code to filter by. hasCountry (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a country. hasState (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a state. hasCity (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a city. hasCounty (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a county. hasPostalCode (boolean) - Filter to addresses that do (`true`) or do not (`false`) have a postal code. addressNotEmpty (boolean) - `true` keeps only addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: total (integer, required) - Total addresses in scope, the sum of `byStatus`. byStatus (AddressStatusCount[], required) - One entry per status present in scope. A status with no addresses is omitted rather than reported as zero. status (PublicAddressStatusEnum, required) - The verification status this count is for. allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK count (integer, required) - Number of addresses in scope with this status. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Update transaction addresses in a batch PUT /addresses/transactions Source: https://docs.trykintsugi.com/reference/2026-07-21/update-transaction-addresses-in-a-batch PUT /addresses/transactions Update transaction addresses in a batch Update the addresses on a batch of transactions in one organization. Identify each address by `id`, or omit `id` and identify it by `transactionId` + `type` to upsert. Setting an address resets its transaction and re-queues address validation. Returns one `UPDATED`/`FAILED` result per input address, in request order; an upsert's result has a null `addressId`. `isUnincorporated` is optional and left unchanged when omitted. Any member of the organization, a partner Owner/Admin or an API key for the organization may edit addresses. A partner Member gets 403, and you get 404 if you do not own the organization. Category: Addresses Request body: addresses (TransactionAddressUpdateItem[], required) - The transaction addresses to update; at most 1000 per request. id (string) - Id of the address to update, or `null` to upsert by transaction and type. transactionId (string, required) - Id of the transaction the address belongs to. type (PublicAddressTypeEnum, required) - Address role to set (`SHIP_TO` or `BILL_TO`). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM street1 (string) - First line of the street address. Omit or send `null` to clear; send a value to set. street2 (string) - Second line of the street address. Omit or send `null` to clear; send a value to set. city (string) - City or locality. Omit or send `null` to clear; send a value to set. county (string) - County or district. Omit or send `null` to clear; send a value to set. state (string) - State or province code. Omit or send `null` to clear; send a value to set. postalCode (string) - Postal or ZIP code. Omit or send `null` to clear; send a value to set. fullAddress (string) - Single-line full address. Omit or send `null` to clear; send a value to set. phone (string) - Contact phone for the address. Omit or send `null` to clear; send a value to set. isUnincorporated (boolean) - When `true`, city-level tax rates are not applied to this address. Omit or send `null` to leave the stored value unchanged; send `false` to clear it. country (string) - ISO-3166 alpha-2 country code. Omit or send `null` to clear; send a value to set. Response fields: [truncated, see the reference page] --- # Validate and enrich an address POST /addresses/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-and-enrich-an-address POST /addresses/validate Validate and enrich an address Validate an address and return the standardized, enriched version of it along with whether it verified and which fields were added or corrected. The address is validated against postal reference data; components such as `county` are filled in when they can be. Returns 400 if the country is not supported, and 503 if the address validation service is temporarily unavailable. Category: Addresses Request body: street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. fullAddress (string) - Single-line full address, as an alternative to fields. phone (string) - Contact phone for the address. country (string) - ISO-3166 alpha-2 country code. Response fields: submittedAddress (PublicAddress, required) - The address exactly as it was submitted. street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. state (string) - State or province code, or `null` when the source supplied none. postalCode (string) - Postal or ZIP code. An empty string when none was supplied. fullAddress (string) - Single-line full address as the source supplied it, or `null` when it supplied none. country (string) - ISO-3166 alpha-2 country code, or `null` when none was supplied. standardizedAddress (PublicAddress, required) - The standardized and enriched version of the submitted address. street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. county (string) - County or district. An empty string when none was supplied. [truncated, see the reference page] --- # List API keys GET /api-keys Source: https://docs.trykintsugi.com/reference/2026-07-21/list-api-keys GET /api-keys List API keys List API keys. Requires a user credential (an Owner or Admin) or a PORTFOLIO-scope Api-Key. Select an organization with an `Organization-Id` to list that organization's keys (`active` toggles current vs archived); omit it to list a portfolio's keys if you are a portfolio Owner or Admin bearer. Paging is forward-only and offset-backed (the cursor encodes a page number, not a keyset bound): pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page, and `previousCursor` / `hasPrevious` are always null/false. On a portfolio listing, optional `scope` (`PORTFOLIO` or `ORGANIZATION`) splits the mixed set for dual-table UIs; omit it for every key. A cursor is only valid for the `limit`, `active`, `scope`, and organization or portfolio it was issued under; change any of those and start from the first page. Category: API Keys Query parameters: active (boolean) - For an organization's own keys, list current (`true`, the default) or archived (`false`) keys. A portfolio or client listing has no archived state, so `false` is rejected there rather than ignored. scope (PublicApiKeyScopeEnum) - On a portfolio listing (no `Organization-Id`), keep only `PORTFOLIO` keys or only `ORGANIZATION` keys (including null-scope legacy keys). Omit for the full mixed set. Rejected on an organization or client listing. allowed values: ORGANIZATION, PORTFOLIO limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (ApiKey[], required) - API keys on this page. id (string, required) - Opaque unique identifier of the API key. Treat as opaque; do not parse. scope (PublicApiKeyScopeEnum, required) - Tier the key grants. `ORGANIZATION` acts on one organization (a direct org key, or a portfolio-minted key for one client); `PORTFOLIO` is a portfolio-wide key for the partner APIs. Null for a key whose stored tier is unrecognized: it grants no access and should be revoked. allowed values: ORGANIZATION, PORTFOLIO organizationId (string, required) - Organization the key acts on for a direct org key, or null for a portfolio-minted key (see `clientOrganizationId`) or a portfolio-wide key. [truncated, see the reference page] --- # Create an API key POST /api-keys Source: https://docs.trykintsugi.com/reference/2026-07-21/create-an-api-key POST /api-keys Create an API key Create an API key and return its one-time secret token (shown only here). Requires a user credential (an Owner or Admin) or a PORTFOLIO-scope Api-Key. Select an organization with an `Organization-Id` to create an organization key (a portfolio Owner/Admin bearer, or a portfolio Api-Key, selecting a client org creates a client-scoped key); omit it to create a portfolio-wide key if you are a portfolio Owner or Admin bearer. Portfolio and client keys are capped: creating one past the cap returns 409. An organization key returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include API keys. Client-scoped and portfolio-wide keys are not plan-gated. Category: API Keys Request body: expiresAt (string) - When the key should expire (RFC-3339 UTC with an explicit Z). Must be in the future. Omit for a key that does not expire. Response fields: id (string, required) - Opaque unique identifier of the created key. Treat as opaque. token (string, required) - The secret API-key token. Shown ONCE, here, at creation; it cannot be retrieved later. Store it securely. Response statuses: 201, 400, 401, 403, 404, 409, 422, 503 --- # Update an API key PATCH /api-keys/{api_key_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-an-api-key PATCH /api-keys/{api_key_id} Update an API key Update an organization API key's expiry. Requires a user credential (an Owner or Admin of the organization, selected with an `Organization-Id`). A PORTFOLIO-scope Api-Key caller still must select a target (403 without one, matching every other verb on this family) but is always refused once it has (404), since client-scoped keys have no update capability for any caller. Only a direct organization key can be updated; any other key returns 404. Send `expiresAt` to set a new expiry or null to remove it; an empty body returns 400. The response is empty on success. Category: API Keys Path parameters: api_key_id (string, required) - Opaque identifier of the API key to update. Treat as opaque. Request body: expiresAt (string) - New expiry for the key (RFC-3339 UTC with an explicit Z), which must be in the future. Send null to remove the expiry so the key never expires. Omit the field and the request is rejected, since there is nothing to change. Response statuses: 204, 400, 401, 403, 404, 409, 422, 503 --- # Revoke an API key DELETE /api-keys/{api_key_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/revoke-an-api-key DELETE /api-keys/{api_key_id} Revoke an API key Revoke an API key. Requires a user credential (an Owner or Admin) or a PORTFOLIO-scope Api-Key. Select an organization with an `Organization-Id` to revoke one of its keys; omit it to revoke a portfolio key if you are a portfolio Owner or Admin bearer. A PORTFOLIO Api-Key caller must always send `Organization-Id` naming a client in its own portfolio and can revoke only that client's keys; it can never revoke the portfolio's own portfolio-wide key. Returns 404 if the key is not one you can revoke; the response is empty on success. Category: API Keys Path parameters: api_key_id (string, required) - Opaque identifier of the API key to revoke. Treat as opaque. Response statuses: 204, 400, 401, 403, 404, 409, 422, 503 --- # List attachments for a related entity GET /attachments Source: https://docs.trykintsugi.com/reference/2026-07-21/list-attachments-for-a-related-entity GET /attachments List attachments for a related entity List the attachments held against one related entity, most recent first. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `relatedEntityId` and `relatedEntityType` are both required. Returns an empty list when the entity has no attachments, or is not one your credential can access. Category: Attachments Query parameters: relatedEntityId (string, required) - The related entity whose attachments to list. relatedEntityType (string, required) - Kind of related entity. Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Upload an attachment POST /attachments Source: https://docs.trykintsugi.com/reference/2026-07-21/upload-an-attachment POST /attachments Upload an attachment Attach a document to a related entity in the resolved organization, as `multipart/form-data` with the file in the `file` part and `relatedEntityId` and `relatedEntityType` as form fields. Returns the stored attachment's metadata. Returns 404 if the related entity does not exist or belongs to an organization your credential cannot access. The file must be at most 10 MB. Category: Attachments Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422 --- # Get an attachment by id GET /attachments/{attachment_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-an-attachment-by-id GET /attachments/{attachment_id} Get an attachment by id Fetch a single attachment's metadata by id. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the attachment does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Category: Attachments Path parameters: attachment_id (string, required) - The unique identifier of the attachment. Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Download an attachment GET /attachments/{attachment_id}/download Source: https://docs.trykintsugi.com/reference/2026-07-21/download-an-attachment GET /attachments/{attachment_id}/download Download an attachment Return an attachment's metadata and a short-lived URL to download its bytes. Searched across every organization your credential owns, so no selector is needed for a known id. Fetch `downloadUrl` directly with a GET; it expires after `expiresInSeconds`. Returns 404 if the attachment does not exist or belongs to an organization your credential cannot access. Category: Attachments Path parameters: attachment_id (string, required) - The unique identifier of the attachment. Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. downloadUrl (string, required) - Time-limited URL to download the attachment bytes. Fetch it directly with a GET; do not send your API credentials to it. It stops working after `expiresInSeconds`, so request this endpoint again for a fresh URL rather than storing it. expiresInSeconds (integer, required) - Seconds from now until `downloadUrl` stops working. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Update bank details PATCH /bank-details Source: https://docs.trykintsugi.com/reference/2026-07-21/update-bank-details PATCH /bank-details Update bank details Partial update of the organization's bank details. Fields you omit keep their stored value; a field sent as null is cleared. Creates the record when none exists. The response masks the account and routing numbers to their last four characters. Admin or Owner only for a user credential; an API key is permitted. The organization is selected by Organization-Id, Connection-Id, or Entity-Id. Category: Bank Details Request body: bankName (string) - Name of the bank. Send null to clear it. accountNumber (string) - Bank account number. Send null to clear it. accountType (PublicBankAccountTypeEnum) - Account type. Send null to clear it. allowed values: CHECKING, SAVINGS accountHolderName (string) - Name on the account. Send null to clear it. routingNumber (string) - Bank routing number. Send null to clear it. Response fields: id (string, required) - Opaque identifier of the bank-details record. bankName (string, required) - Name of the bank, or null when not captured. accountNumberLast4 (string, required) - Last four characters of the account number, or null when not captured. accountType (PublicBankAccountTypeEnum, required) - Account type, or null when not captured. allowed values: CHECKING, SAVINGS accountHolderName (string, required) - Name on the account, or null when not captured. routingNumberLast4 (string, required) - Last four characters of the routing number, or null when not captured. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get the organization's chargebee subscription GET /billing Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-organization-s-chargebee-subscription GET /billing Get the organization's chargebee subscription Returns the plan, subscription, customer, and payment method for the org selected by Organization-Id, Connection-Id, or Entity-Id. subscription, customer, and card are null when the org never checked out or Chargebee is degraded; hasBillingAccount and hasDefaultPaymentMethod tell the cases apart. Category: Billing Response fields: billingPlan (PublicBillingPlanEnum, required) - The organization's plan. allowed values: FREE, GROWTH, PREMIUM subscriptionId (string) - Chargebee subscription id, or null if unset. subscription (Subscription) - The Chargebee subscription, or null if unset. id (string, required) - Chargebee subscription id. status (PublicSubscriptionStatusEnum, required) - Subscription status. allowed values: FUTURE, IN_TRIAL, ACTIVE, NON_RENEWING, PAUSED, CANCELLED, TRANSFERRED currency (PublicCurrencyEnum, required) - ISO-4217 currency for all amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) billingPeriod (integer, required) - Length of one billing cycle. billingPeriodUnit (string, required) - Unit for `billingPeriod`, e.g. `month` or `year`. currentTermStart (string) - Start of the current billing term. currentTermEnd (string) - End of the current billing term. nextBillingAt (string) - When the next invoice is expected. coupon (string) - Coupon code applied to the subscription, if any. items (SubscriptionItem[], required) - Priced lines on the subscription. itemPriceId (string, required) - Chargebee item price id for this line. itemType (string, required) - Kind of line, e.g. `plan`, `addon`, or `charge`. quantity (integer) - Quantity, when metered. unitPrice (string, required) - Price per unit, in the subscription's currency. amount (string) - Total amount for this line, when set. customer (BillingCustomer) - The Chargebee customer, or null if unset. email (string, required) - Billing contact email address. billingAddress (BillingAddress) - Billing contact address, or null if not captured. firstName (string) - Contact first name. lastName (string) - Contact last name. line1 (string) - Street address line 1. line2 (string) - Street address line 2. city (string) - City. state (string) - State or province name. [truncated, see the reference page] --- # Update the organization's billing contact email PATCH /billing Source: https://docs.trykintsugi.com/reference/2026-07-21/update-the-organization-s-billing-contact-email PATCH /billing Update the organization's billing contact email Updates the Chargebee billing contact email for the org selected by Organization-Id, Connection-Id, or Entity-Id. Requires a Chargebee customer to already exist (set on first checkout or portal session). Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Request body: email (string, required) - New billing contact email address. Response fields: email (string, required) - Billing contact email address. billingAddress (BillingAddress) - Billing contact address, or null if not captured. firstName (string) - Contact first name. lastName (string) - Contact last name. line1 (string) - Street address line 1. line2 (string) - Street address line 2. city (string) - City. state (string) - State or province name. stateCode (string) - State or province code. country (string) - ISO country code or name as stored by Chargebee. zip (string) - Postal code. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get the organization's billing history chart GET /billing/analytics Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-organization-s-billing-history-chart GET /billing/analytics Get the organization's billing history chart Returns up to 12 months of invoiced and pending amounts for the org selected by Organization-Id, Connection-Id, or Entity-Id. Empty when the organization has no Chargebee subscription. Category: Billing Response fields: months (BillingChartMonth[], required) - One entry per month. label (string, required) - Three-letter month abbreviation, e.g. `Oct`. month (integer, required) - Month number (1-12). year (integer, required) - Calendar year. amount (string, required) - Total amount for the month. currency (PublicCurrencyEnum, required) - ISO-4217 currency of `amount`. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) status (PublicBillingChartStatusEnum, required) - Whether the month is invoiced, still pending, or has no activity. allowed values: invoiced, pending, no_actions Response statuses: 200, 400, 401, 404, 422 --- # Start a hosted chargebee checkout POST /billing/checkout Source: https://docs.trykintsugi.com/reference/2026-07-21/start-a-hosted-chargebee-checkout POST /billing/checkout Start a hosted chargebee checkout Creates a one-time hosted checkout URL for the org selected by Organization-Id, Connection-Id, or Entity-Id to subscribe to the given plan. `PREMIUM` checks out at the org's preset price; `GROWTH` checks out at the standard metered price. `FREE` is not checkout-able. Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Request body: billingPlan (PublicBillingWritePlanEnum, required) - Plan tier to check out into. `FREE` is not checkout-able. allowed values: GROWTH, PREMIUM Response fields: id (string, required) - Chargebee hosted page id. url (string, required) - One-time hosted checkout URL. Treat as a secret. state (string, required) - Hosted page lifecycle state, e.g. `created`. expiresAt (string, required) - When the checkout URL expires. Response statuses: 201, 400, 401, 403, 404, 409, 422 --- # Get the organization's billing-lock detail GET /billing/details Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-organization-s-billing-lock-detail GET /billing/details Get the organization's billing-lock detail Returns the plan, subscription status, and effective entitlement for the org selected by Organization-Id, Connection-Id, or Entity-Id. This is what gates access to most of the product. Category: Billing Response fields: billingPlan (PublicBillingPlanEnum, required) - The organization's plan. allowed values: FREE, GROWTH, PREMIUM subscriptionStatus (PublicSubscriptionStatusEnum, required) - Lifecycle status of the Chargebee subscription. allowed values: FUTURE, IN_TRIAL, ACTIVE, NON_RENEWING, PAUSED, CANCELLED, TRANSFERRED effectiveEntitlement (PublicEffectiveEntitlementEnum, required) - Effective feature tier, which can read higher than `billingPlan` for a partner-associated or test organization. allowed values: FREE, PAID, PREMIUM billingPreset (PublicBillingPresetEnum) - Sales-led Premium staging while the organization is still FREE. Does not unlock Premium entitlements by itself. allowed values: NONE, PREMIUM capabilities (CapabilityAccess[], required) - Access to each capability, one entry per capability. `null` when access does not depend on per-capability settings for this organization; gate on `effectiveEntitlement` instead. capability (string, required) - The capability. New values may be added; ignore a capability you do not gate on. allowed values: USE_TAX, ECM, CUSTOM_ANALYTICS, FILING_READY_REPORTS, TAX_ENGINE, API_KEYS, KINTSUGI_MAIL, MANAGED_REGISTRATIONS, MANAGED_FILINGS access (PublicCapabilityAccessEnum, required) - Whether the organization may use the capability. allowed values: INCLUDED, NOT_INCLUDED, REQUIRES_PAID_PLAN Response statuses: 200, 400, 401, 404, 422 --- # Get the current month's billing estimate GET /billing/estimate Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-current-month-s-billing-estimate GET /billing/estimate Get the current month's billing estimate Returns the estimated charge for the current billing month for the org selected by Organization-Id, Connection-Id, or Entity-Id. Requires a paid plan, an active partner association, or a test organization. Category: Billing Response fields: filings (integer, required) - Billable filings completed so far this month. registrations (integer, required) - Billable registrations completed so far this month. unitCost (string, required) - Price per filing or registration on the Growth plan. currency (PublicCurrencyEnum, required) - ISO-4217 currency of the amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) premium (boolean, required) - Whether the organization is on the Premium plan. estimatedAmount (string, required) - Estimated charge for the current month: the flat Premium price, or unitCost times the combined filings and registrations count. Response statuses: 200, 400, 401, 403, 404, 422 --- # List the organization's invoices GET /billing/invoices Source: https://docs.trykintsugi.com/reference/2026-07-21/list-the-organization-s-invoices GET /billing/invoices List the organization's invoices Returns up to the last 12 months of Chargebee invoices for the org selected by Organization-Id, Connection-Id, or Entity-Id, newest first. Empty when the organization has no Chargebee subscription. Category: Billing Response fields: id (string, required) - Chargebee invoice id. status (string, required) - Invoice status as reported by Chargebee. currency (PublicCurrencyEnum) - ISO-4217 currency for all amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) recurring (boolean, required) - Whether this invoice is a recurring charge. date (string) - When the invoice was issued. dueDate (string) - When payment is due. paidAt (string) - When the invoice was paid, or null if unpaid. subTotal (string) - Charges before tax. tax (string) - Total tax charged. total (string) - Total invoice amount. amountPaid (string) - Amount paid so far. amountDue (string) - Amount still owed. lineItems (InvoiceLineItem[], required) - Charges on this invoice. entityId (string) - Id of the priced entity this line bills, if any. description (string, required) - Human-readable description of the charge. amount (string) - Line amount. issuedCreditNotes (CreditNote[], required) - Credit notes issued against this invoice. id (string, required) - Chargebee credit note id. total (string, required) - Total credited amount. status (string, required) - Credit note status as reported by Chargebee. Response statuses: 200, 400, 401, 404, 422 --- # Download one invoice as a PDF GET /billing/invoices/{invoice_id}/pdf Source: https://docs.trykintsugi.com/reference/2026-07-21/download-one-invoice-as-a-pdf GET /billing/invoices/{invoice_id}/pdf Download one invoice as a PDF Downloads one Chargebee invoice as a PDF file, for the org selected by Organization-Id, Connection-Id, or Entity-Id. Category: Billing Path parameters: invoice_id (string, required) Response statuses: 200, 400, 401, 404, 422, 503 --- # Get usage detail for one invoice GET /billing/invoices/{invoice_id}/usage Source: https://docs.trykintsugi.com/reference/2026-07-21/get-usage-detail-for-one-invoice GET /billing/invoices/{invoice_id}/usage Get usage detail for one invoice Returns the parsed usage lines billed on one invoice, for the org selected by Organization-Id, Connection-Id, or Entity-Id. Category: Billing Path parameters: invoice_id (string, required) Response fields: state (string) - US state or Canadian province code, if applicable. requestType (string) - Kind of billable action, e.g. `filing`. completionDate (string, required) - Date the billed action completed, as reported by Chargebee. country (string) - ISO country code. Response statuses: 200, 400, 401, 404, 422 --- # Update the organization's subscription plan PATCH /billing/plan Source: https://docs.trykintsugi.com/reference/2026-07-21/update-the-organization-s-subscription-plan PATCH /billing/plan Update the organization's subscription plan Moves the existing Chargebee subscription of the org selected by Organization-Id, Connection-Id, or Entity-Id to the given plan. Requires a subscription to already exist; use POST /billing/checkout for a first-time checkout. Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Request body: billingPlan (PublicBillingWritePlanEnum, required) - Plan tier to update the existing subscription to. allowed values: GROWTH, PREMIUM Response fields: id (string, required) - Chargebee subscription id. status (PublicSubscriptionStatusEnum, required) - Subscription status. allowed values: FUTURE, IN_TRIAL, ACTIVE, NON_RENEWING, PAUSED, CANCELLED, TRANSFERRED currency (PublicCurrencyEnum, required) - ISO-4217 currency for all amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) billingPeriod (integer, required) - Length of one billing cycle. billingPeriodUnit (string, required) - Unit for `billingPeriod`, e.g. `month` or `year`. currentTermStart (string) - Start of the current billing term. currentTermEnd (string) - End of the current billing term. nextBillingAt (string) - When the next invoice is expected. coupon (string) - Coupon code applied to the subscription, if any. items (SubscriptionItem[], required) - Priced lines on the subscription. itemPriceId (string, required) - Chargebee item price id for this line. itemType (string, required) - Kind of line, e.g. `plan`, `addon`, or `charge`. quantity (integer) - Quantity, when metered. unitPrice (string, required) - Price per unit, in the subscription's currency. amount (string) - Total amount for this line, when set. Response statuses: 200, 400, 401, 403, 404, 422 --- # Create a chargebee self-serve customer portal session POST /billing/portal-session Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-chargebee-self-serve-customer-portal-session POST /billing/portal-session Create a chargebee self-serve customer portal session Creates a Chargebee self-serve customer portal session (URL, token, and the fields Chargebee.js needs) for the org selected by Organization-Id, Connection-Id, or Entity-Id. Creates the Chargebee customer record on first use, billed to the authenticated identity's name and email. Requires an owner or admin of the organization, or the organization's own API key. Category: Billing Response fields: id (string, required) - Chargebee portal session id. token (string, required) - Portal session token. Treat as a secret. accessUrl (string, required) - One-time portal URL. Treat as a secret. status (string, required) - Portal session status, e.g. `created`. createdAt (string, required) - When the session was created. expiresAt (string, required) - When the portal URL expires. object (string, required) - Chargebee object type, `portal_session`. customerId (string, required) - Chargebee customer id the session is for. redirectUrl (string) - Where the portal sends the user on exit, or null. linkedCustomers (PortalLinkedCustomer[], required) - Other Chargebee customers reachable from this session. customerId (string, required) - Chargebee customer id. email (string, required) - Email of the linked customer. hasActiveSubscription (boolean, required) - Whether the linked customer has an active subscription. hasBillingAddress (boolean, required) - Whether the linked customer has a billing address on file. hasPaymentMethod (boolean, required) - Whether the linked customer has a payment method on file. object (string, required) - Chargebee object type, `linked_customer`. Response statuses: 201, 400, 401, 403, 404, 422 --- # Get unbilled usage since the last invoice GET /billing/unbilled-usages Source: https://docs.trykintsugi.com/reference/2026-07-21/get-unbilled-usage-since-the-last-invoice GET /billing/unbilled-usages Get unbilled usage since the last invoice Returns completed actions not yet reflected on an invoice, for a Growth-plan org selected by Organization-Id, Connection-Id, or Entity-Id. Empty for any other plan or a Growth org with no Chargebee subscription yet. Category: Billing Response fields: actions (UnbilledAction[], required) - Completed, unbilled actions. actionType (PublicUnbilledActionTypeEnum, required) - Kind of action. allowed values: Filing, Registration, Deregistration jurisdiction (string, required) - Jurisdiction name where the action occurred. completed (string, required) - Date the action completed. country (string, required) - ISO country code where the action occurred. count (integer, required) - Total number of unbilled actions. unitCost (string, required) - Price per action from the current Chargebee subscription. currency (PublicCurrencyEnum, required) - ISO-4217 currency of the amounts. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) nextBillingAt (string) - When the next invoice is expected. lastInvoice (LastInvoiceSummary) - Summary of the last invoice, or null if none exists. amount (string) - Total amount of the last invoice. paidAt (string) - When the last invoice was paid, or null if unpaid. Response statuses: 200, 400, 401, 404, 422, 503 --- # List certificate imports by review status GET /certificate-imports Source: https://docs.trykintsugi.com/reference/2026-07-21/list-certificate-imports-by-review-status GET /certificate-imports List certificate imports by review status List certificate imports filtered by review status, so a client can build a review queue. Repeat the `status` query parameter for multiple values (e.g. `?status=NEEDS_REVIEW&status=READY_TO_APPROVE`). Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Returns an empty list when nothing matches. Category: Certificate Imports Query parameters: status (string[], required) - Review status filter. Repeat for multiple values. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED customerId (string, required) - Customer that OCR matched this certificate to, or null when no customer has been matched. customerMatchStatus (PublicCustomerMatchStatusEnum, required) - Outcome of the OCR customer match, or null before matching has run. allowed values: MATCHED, SUGGESTED, UNMATCHED createdAt (string, required) - When the import was created, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When the import was last updated, as an RFC-3339 UTC timestamp; equal to createdAt for an import that has not been modified since creation. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Approve multiple certificate imports POST /certificate-imports/bulk-approve Source: https://docs.trykintsugi.com/reference/2026-07-21/approve-multiple-certificate-imports POST /certificate-imports/bulk-approve Approve multiple certificate imports Approve several certificate imports in the resolved organization in one request, each with its own approval values. This is non-atomic: each import is approved independently, so a failure on one does not roll back the others. The response carries a per-import outcome, with an `error` on any that failed. Returns 404 if the resolved organization is not one your credential can access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Request body: items (CertificateImportBulkApproveItem[], required) - The certificate imports to approve, each with its approval values. customerId (string, required) - Customer to link the created exemption(s) to. jurisdictions (string[], required) - Two-letter jurisdiction codes to create an exemption for; one exemption is created per entry. exemptionType (string) - Exemption type to create: `customer`, `wholesale`, or `transaction`. startDate (string, required) - Exemption start date as `YYYY-MM-DD`. endDate (string) - Exemption end date as `YYYY-MM-DD`, or null when the exemption does not expire. fein (string) - Federal Employer Identification Number, or null if not provided. salesTaxId (string) - State sales tax ID or permit number, or null if not provided. buyerBusinessName (string) - Corrected buyer business name to persist, or null to leave it unchanged. sellerBusinessName (string) - Corrected seller business name to persist, or null to leave it unchanged. certificateImportId (string, required) - Kintsugi's unique identifier for the certificate import to approve. Response fields: total (integer, required) - Number of imports in the request. approved (integer, required) - Number of imports that were approved. failed (integer, required) - Number of imports that failed to approve. results (CertificateImportBulkApproveResultItem[], required) - Per-import outcome, in request order. certificateImportId (string, required) - The certificate import this result is for. status (PublicBulkApproveResultStatusEnum, required) - Whether this import was approved or failed. Branch on this, not the error message. allowed values: approved, failed [truncated, see the reference page] --- # Confirm a bulk certificate upload POST /certificate-imports/confirm-upload Source: https://docs.trykintsugi.com/reference/2026-07-21/confirm-a-bulk-certificate-upload POST /certificate-imports/confirm-upload Confirm a bulk certificate upload Confirm that files finished uploading to S3, so they can be processed for OCR review. Send the `uploadSessionId` from initiating the upload and the `certificateImportIds` that uploaded successfully. Returns 404 if the session does not exist or belongs to an organization your credential cannot access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Request body: uploadSessionId (string, required) - The uploadSessionId returned from initiating the upload. certificateImportIds (string[], required) - The certificateImportIds that were successfully uploaded to S3. Response fields: confirmedCount (integer, required) - Number of files confirmed and queued for OCR processing. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List certificate imports by upload session GET /certificate-imports/sessions/{upload_session_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/list-certificate-imports-by-upload-session GET /certificate-imports/sessions/{upload_session_id} List certificate imports by upload session List every certificate import in one upload session, so a client can watch OCR review progress. Searched across every organization your credential owns, so no selector is needed for a known session. Returns 404 if the session does not exist or belongs to an organization your credential cannot access. Category: Certificate Imports Path parameters: upload_session_id (string, required) - The upload session to list imports for. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED customerId (string, required) - Customer that OCR matched this certificate to, or null when no customer has been matched. customerMatchStatus (PublicCustomerMatchStatusEnum, required) - Outcome of the OCR customer match, or null before matching has run. allowed values: MATCHED, SUGGESTED, UNMATCHED createdAt (string, required) - When the import was created, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When the import was last updated, as an RFC-3339 UTC timestamp; equal to createdAt for an import that has not been modified since creation. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Initiate a bulk certificate upload POST /certificate-imports/upload-urls Source: https://docs.trykintsugi.com/reference/2026-07-21/initiate-a-bulk-certificate-upload POST /certificate-imports/upload-urls Initiate a bulk certificate upload Begin a bulk certificate upload in the resolved organization. Creates a certificate-import row per file and returns an `uploadSessionId` plus a presigned S3 upload target for each. POST each file as `multipart/form-data` to its `uploadUrl` including every `uploadFields` entry, then call the confirm endpoint with the same `uploadSessionId`. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Request body: files (CertificateImportFile[], required) - The files to upload in this batch. fileName (string, required) - Original filename including extension. The extension must be one of .jpeg, .jpg, .pdf, .png, .zip. mimeType (string, required) - Media type of the file. Response fields: uploadSessionId (string, required) - Identifier grouping every file in this upload batch. Pass it to the confirm and list-by-session endpoints. files (CertificateImportUploadTarget[], required) - One presigned upload target per requested file. certificateImportId (string, required) - Kintsugi's unique identifier for the created certificate import. fileName (string, required) - The filename this upload target is for. uploadUrl (string, required) - Short-lived S3 URL to POST the file's bytes to as `multipart/form-data`. uploadFields (CertificateUploadField[], required) - Form fields to include in the multipart POST alongside the file. key (string, required) - Form field name to send in the multipart upload. value (string, required) - Value to send for this form field. Response statuses: 201, 400, 401, 403, 404, 409, 422 --- # Approve a certificate import POST /certificate-imports/{certificate_import_id}/approve Source: https://docs.trykintsugi.com/reference/2026-07-21/approve-a-certificate-import POST /certificate-imports/{certificate_import_id}/approve Approve a certificate import Approve a reviewed certificate import in the resolved organization. Creates one exemption per entry in `jurisdictions`, links each to `customerId`, attaches the uploaded file, and moves the import to `APPROVED`. Send the final (possibly reviewer-corrected) certificate values in the body. Returns the updated import. Returns 409 if the import is not in a reviewable state (for example, already approved or rejected), and 404 if it does not exist or belongs to an organization your credential cannot access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Path parameters: certificate_import_id (string, required) - The unique identifier of the certificate import to approve. Request body: customerId (string, required) - Customer to link the created exemption(s) to. jurisdictions (string[], required) - Two-letter jurisdiction codes to create an exemption for; one exemption is created per entry. exemptionType (string) - Exemption type to create: `customer`, `wholesale`, or `transaction`. startDate (string, required) - Exemption start date as `YYYY-MM-DD`. endDate (string) - Exemption end date as `YYYY-MM-DD`, or null when the exemption does not expire. fein (string) - Federal Employer Identification Number, or null if not provided. salesTaxId (string) - State sales tax ID or permit number, or null if not provided. buyerBusinessName (string) - Corrected buyer business name to persist, or null to leave it unchanged. sellerBusinessName (string) - Corrected seller business name to persist, or null to leave it unchanged. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED [truncated, see the reference page] --- # Get a certificate import's file URL GET /certificate-imports/{certificate_import_id}/file-url Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-certificate-import-s-file-url GET /certificate-imports/{certificate_import_id}/file-url Get a certificate import's file URL Return a short-lived URL to download an imported certificate's file. Searched across every organization your credential owns, so no selector is needed for a known id. Fetch `url` directly with a GET; it expires after `expiresInSeconds`. Returns 404 if the import does not exist or belongs to an organization your credential cannot access. Category: Certificate Imports Path parameters: certificate_import_id (string, required) - The unique identifier of the certificate import. Response fields: url (string, required) - Short-lived S3 URL to GET the file's bytes. expiresInSeconds (integer, required) - Lifetime of `url` in seconds; request the endpoint again for a fresh one after it expires. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Reject a certificate import POST /certificate-imports/{certificate_import_id}/reject Source: https://docs.trykintsugi.com/reference/2026-07-21/reject-a-certificate-import POST /certificate-imports/{certificate_import_id}/reject Reject a certificate import Reject a certificate import in the resolved organization, moving it to `REJECTED` and out of the review queue. Returns the updated import. Returns 409 if the import has already been approved, and 404 if it does not exist or belongs to an organization your credential cannot access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Certificate Imports Path parameters: certificate_import_id (string, required) - The unique identifier of the certificate import to reject. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate import. uploadSessionId (string, required) - Identifier of the upload batch this import belongs to. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the uploaded file. reviewStatus (PublicCertificateImportReviewStatusEnum, required) - Where this import sits in the OCR review flow. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED customerId (string, required) - Customer that OCR matched this certificate to, or null when no customer has been matched. customerMatchStatus (PublicCustomerMatchStatusEnum, required) - Outcome of the OCR customer match, or null before matching has run. allowed values: MATCHED, SUGGESTED, UNMATCHED createdAt (string, required) - When the import was created, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When the import was last updated, as an RFC-3339 UTC timestamp; equal to createdAt for an import that has not been modified since creation. Response statuses: 200, 400, 401, 403, 404, 409, 422, 500 --- # List compliance document catalog GET /compliance-documents Source: https://docs.trykintsugi.com/reference/2026-07-21/list-compliance-document-catalog GET /compliance-documents List compliance document catalog Returns every catalog type for the selected organization, with upload status and any stored files. Requires a user credential (an API key is rejected) that is an Owner of the organization selected by Organization-Id, Connection-Id, or Entity-Id. Category: Compliance Documents Response fields: id (string, required) - Stable catalog type id for this compliance document slot. allowed values: acquisition_documentation, articles_of_incorporation, bank_account_certificate, bank_statement, business_license, business_registration_certificate, certificate_of_authority, certificate_of_formation, certificate_of_incorporation, customs_documents, dba_registration_document, drivers_license (and 18 more, see the reference page) label (string, required) - Human-readable label for the catalog type. cardinality (PublicComplianceDocumentCardinality, required) - Whether this type holds one file or many. One-file types are replaced with PUT on the catalog type. Many-file types add with POST on the catalog type and replace a single file with PUT on that file. Deleting a file is not available yet. allowed values: ONE, MANY status (PublicComplianceDocumentStatus, required) - Whether any file is stored for this catalog type. allowed values: UPLOADED, NOT_UPLOADED lastUpdated (string, required) - Most recent create or replace among this type's files, or `null` when none are uploaded. documents (ComplianceDocumentFile[], required) - Files currently stored for this catalog type. id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Replace one file under a many-file compliance document type PUT /compliance-documents/files/{document_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/replace-one-file-under-a-many-file-compliance-document-type PUT /compliance-documents/files/{document_id} Replace one file under a many-file compliance document type Replace the bytes of one stored file under a many-file catalog type, as `multipart/form-data` with the file in the `file` part. Returns 400 when the file belongs to a one-file catalog type. The file must be a PDF, JPG, or PNG of at most 10 MB. Requires an Owner user credential. Category: Compliance Documents Path parameters: document_id (string, required) - The unique identifier of the stored file. Response fields: id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 200, 400, 401, 403, 404, 409, 413, 422, 500, 503 --- # Preview a compliance document file GET /compliance-documents/files/{document_id}/preview Source: https://docs.trykintsugi.com/reference/2026-07-21/preview-a-compliance-document-file GET /compliance-documents/files/{document_id}/preview Preview a compliance document file Return a stored file's bytes for display in a viewer. The response is the file itself, not JSON: `Content-Type` is the stored file's type and `Content-Disposition` is `inline`, so a browser renders it rather than saving it. Returns 404 if the file does not exist or belongs to an organization your credential cannot access. Requires an Owner user credential. Category: Compliance Documents Path parameters: document_id (string, required) - The unique identifier of the stored file. Response statuses: 200, 400, 401, 403, 404, 409, 422, 503 --- # Add a file to a many-file compliance document type POST /compliance-documents/{catalog_type} Source: https://docs.trykintsugi.com/reference/2026-07-21/add-a-file-to-a-many-file-compliance-document-type POST /compliance-documents/{catalog_type} Add a file to a many-file compliance document type Add a file under a many-file catalog type, as `multipart/form-data` with the file in the `file` part. Returns 400 when the catalog type holds only one file. The file must be a PDF, JPG, or PNG of at most 10 MB. Requires an Owner user credential. Category: Compliance Documents Path parameters: catalog_type (string, required) - Catalog type id. allowed values: acquisition_documentation, articles_of_incorporation, bank_account_certificate, bank_statement, business_license, business_registration_certificate, certificate_of_authority, certificate_of_formation, certificate_of_incorporation, customs_documents, dba_registration_document, drivers_license (and 18 more, see the reference page) Response fields: id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422, 500, 503 --- # Add or replace a one-file compliance document PUT /compliance-documents/{catalog_type} Source: https://docs.trykintsugi.com/reference/2026-07-21/add-or-replace-a-one-file-compliance-document PUT /compliance-documents/{catalog_type} Add or replace a one-file compliance document Put the single file for a one-file catalog type, as `multipart/form-data` with the file in the `file` part. Creates the slot on first upload and replaces the stored file after that. A replace deletes the previous file and returns a new `id`; do not reuse the old id for preview. Returns 400 when the catalog type holds many files. The file must be a PDF, JPG, or PNG of at most 10 MB. Requires an Owner user credential. Category: Compliance Documents Path parameters: catalog_type (string, required) - Catalog type id. allowed values: acquisition_documentation, articles_of_incorporation, bank_account_certificate, bank_statement, business_license, business_registration_certificate, certificate_of_authority, certificate_of_formation, certificate_of_incorporation, customs_documents, dba_registration_document, drivers_license (and 18 more, see the reference page) Response fields: id (string, required) - Kintsugi's unique identifier for the stored file. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. createdAt (string, required) - When the file was first stored, as an RFC-3339 UTC timestamp. updatedAt (string, required) - When this stored row was last written, as an RFC-3339 UTC timestamp. Set when the file is created (same moment as `createdAt`) and again when `PUT /compliance-documents/files/{id}` overwrites that id. A one-file PUT on the catalog type mints a new id, so both timestamps are the time of that new row. Response statuses: 200, 400, 401, 403, 404, 409, 413, 422, 500, 503 --- # List connections GET /connections Source: https://docs.trykintsugi.com/reference/2026-07-21/list-connections GET /connections List connections List connections across every organization your credential can access (portfolio-wide), keyset-paginated. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Each connection maps a platform entity (`platformEntityId`) to an organization (`organizationId`), so an integration can discover which entity belongs to which org. Optionally narrow with `status` / `source` and order with `sort` / `order`; a cursor is only valid for the sort, the filters, AND the organization scope it was issued under -- change any of them and start again from the first page. Category: Connections Query parameters: status (string) - Comma-separated connection statuses (ACTIVE, INACTIVE, CONNECTION_ERROR); matches any of them. Unknown tokens are rejected with 400. source (string) - Comma-separated integration sources; matches any of them. Unknown tokens are rejected with 400. sort (PublicConnectionSortEnum) - Field to sort by. Omit for the default order: `ACTIVE` connections first, then `INACTIVE`, then `CONNECTION_ERROR`, each with the most recently updated first (`order` applies only when `sort` is set). Every offered key sorts the whole matching set, so expect a slower first page on a large portfolio. allowed values: createdAt, updatedAt, lastSynced, storeName, status, source, recordsSynced order (PublicConnectionSortOrder) - Sort direction when `sort` is set. Defaults to `desc`. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Connection[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. [truncated, see the reference page] --- # Start an acumatica oauth connect POST /connections/acumatica/oauth/authorize Source: https://docs.trykintsugi.com/reference/2026-07-21/start-an-acumatica-oauth-connect POST /connections/acumatica/oauth/authorize Start an acumatica oauth connect Return the Acumatica consent URL for the resolved organization's self-hosted instance. `clientId`/`clientSecret` are the OAuth app registered on that instance; never echoed back. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Request body: instanceUrl (string, required) - Acumatica instance base URL. clientId (string, required) - Acumatica OAuth client id. clientSecret (string, required) - Acumatica OAuth client secret. endpointVersion (string) - Acumatica contract endpoint version. endpointName (string) - Acumatica contract endpoint name. branchId (string) - Optional branch scope applied after OAuth. Response fields: authUrl (string, required) - Consent URL to redirect the user to. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Start an airwallex oauth connect POST /connections/airwallex/oauth/authorize Source: https://docs.trykintsugi.com/reference/2026-07-21/start-an-airwallex-oauth-connect POST /connections/airwallex/oauth/authorize Start an airwallex oauth connect Return the Airwallex consent URL for the resolved organization. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Response fields: authUrl (string, required) - Airwallex consent URL. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Delete an unfinished apideck connection DELETE /connections/apideck/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/delete-an-unfinished-apideck-connection DELETE /connections/apideck/{conn_id} Delete an unfinished apideck connection Remove a connection left over from a Vault flow that was cancelled or failed before activation. Only an `inactive` or `connection_error` Apideck connection that holds no data is removed, permanently: no archived row, note or audit entry is kept. Returns 409 if the connection is active (for example the activate call succeeded but its response was lost) or already holds data; nothing is changed, so it is safe to call again after a failed or uncertain activate. Returns 404 if the connection does not exist, is not an Apideck-backed connection, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. To disconnect a working connection, use `DELETE /connections/{connId}`. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Activate an apideck-backed connection POST /connections/apideck/{conn_id}/activate Source: https://docs.trykintsugi.com/reference/2026-07-21/activate-an-apideck-backed-connection POST /connections/apideck/{conn_id}/activate Activate an apideck-backed connection Activate an Apideck-backed connection after the Vault widget flow completes, with duplicate-connection handling by `shopId` (e.g. the QuickBooks realmId or the WooCommerce shop domain). Omit `shopId` to have the platform verify the Vault connection and resolve it automatically. If another connection already exists for the same `shopId`, that one is reactivated and this one is superseded. Returns 400 if the connection is not an Apideck-backed connection. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Apideck Vault call itself fails; retrying may succeed. Returns 400 with code `already_connected` when `shopId` matched a connection you already have: that connection was reactivated (and given any NetSuite or DualEntry values sent here), this one was deleted, and nothing further is needed. Send `netsuiteAccountId`, `netsuiteSubsidiaryId` or `dualentryCompanyId` here, not in a settings update beforehand, so they land on the connection that stays. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: shopId (string) - Store/company identifier for duplicate-connection checking (e.g. the QuickBooks realmId or the WooCommerce shop domain). Omit to have the platform verify the Vault connection and resolve it automatically. netsuiteAccountId (string) - NetSuite only: the account id from Vault. Written to the connection this activate keeps, which is the existing connection when `shopId` matches one. Omit to leave the stored value unchanged. Ignored for other sources. netsuiteSubsidiaryId (string) - NetSuite only: the subsidiary id from Vault. Written like `netsuiteAccountId`. Omit to leave the stored value unchanged. Ignored for other sources. dualentryCompanyId (string) - DualEntry only: the company id from Vault. Written like `netsuiteAccountId`. Omit to leave the stored value unchanged; send `null` or an empty string to scope the connection to every company. Ignored for other sources. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. [truncated, see the reference page] --- # Open an apideck vault session to edit a connection GET /connections/apideck/{conn_id}/session Source: https://docs.trykintsugi.com/reference/2026-07-21/open-an-apideck-vault-session-to-edit-a-connection GET /connections/apideck/{conn_id}/session Open an apideck vault session to edit a connection Open an Apideck Vault session for an existing connection, to re-open the widget for re-authentication or editing stored credentials. Returns 404 if the connection does not exist, is not an Apideck-backed connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 400 if Apideck rejects the Vault session request. Returns 503 if the Vault session call itself fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: sessionToken (string, required) - Apideck Vault session token to edit credentials. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Connect an apideck-backed service POST /connections/apideck/{service_id}/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-an-apideck-backed-service POST /connections/apideck/{service_id}/connect Connect an apideck-backed service Open an Apideck Vault session to connect one of the Apideck-backed services (BigCommerce, QuickBooks, Deel, Rippling, Gusto, WooCommerce, Amazon Seller Central, Etsy, Walmart, Magento, Shopware, Xero, NetSuite, Sage Intacct, Wix, Microsoft Dynamics 365 Business Central, DualEntry, Intuit Enterprise Suite). The returned `token` opens the Vault widget; complete the OAuth/credential flow there, then call the activate route with the resulting `connectionId`. `shopId`/`shopUrl` apply only to Shopware. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Vault session call fails; retrying may succeed. Category: Connections Path parameters: service_id (ApiDeckServiceEnum, required) - The Apideck service to connect. allowed values: bigcommerce, quickbooks, deel, rippling, gusto, woocommerce, amazon-seller-central, etsy, walmart, magento, shopware, xero (and 6 more, see the reference page) Request body: defaultCountry (CountryCodeEnum) - Default country for transactions imported through this connection. allowed values: AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM (and 239 more, see the reference page) shopId (string) - Shopware only: the shop's Apideck shop id. shopUrl (string) - Shopware only: the shop's storefront URL. Response fields: connectionId (string, required) - The new connection's id, INACTIVE until Vault activation completes. token (string, required) - Apideck Vault session token to open the connect widget. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Connect a bill.com account POST /connections/bill-com/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-bill-com-account POST /connections/bill-com/connect Connect a bill.com account Create or update a Bill.com connection (single organization per connection). Re-submitting the same `billComOrganizationId` updates its stored credentials rather than creating a second connection. Returns 409 if that Bill.com organization is already ACTIVE on a different Kintsugi organization; deactivate it there first. Returns 503 if Bill.com sync-token auth is not configured. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: syncTokenName (string, required) - Bill.com sync-token name (username). syncTokenValue (string, required) - Bill.com sync-token value (password). billComOrganizationId (string, required) - Bill.com organization id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate bill.com credentials POST /connections/bill-com/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-bill-com-credentials POST /connections/bill-com/validate Validate bill.com credentials Probe Bill.com sync-token credentials without persisting a connection, returning the entity available under them. Returns 400 if authentication fails. Returns 409 if that Bill.com organization is already ACTIVE on a different Kintsugi organization. Returns 503 if Bill.com sync-token auth is not configured. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: syncTokenName (string, required) - Bill.com sync-token name (username). syncTokenValue (string, required) - Bill.com sync-token value (password). billComOrganizationId (string, required) - Bill.com organization id. Response fields: entities (BillComValidateEntity[]) - Entities available under the validated credentials. id (string, required) - Bill.com entity id. name (string, required) - Bill.com entity display name. currency (string) - Entity base currency. Response statuses: 200, 400, 401, 403, 404, 409, 422, 503 --- # Enable tax collection on a bill.com connection POST /connections/bill-com/{conn_id}/enable-tax Source: https://docs.trykintsugi.com/reference/2026-07-21/enable-tax-collection-on-a-bill-com-connection POST /connections/bill-com/{conn_id}/enable-tax Enable tax collection on a bill.com connection Provision the Bill.com invoice webhook subscription (if needed) and enable tax calculation (L2) on a Bill.com connection. Unlike the generic enable-tax-collection action, this is required before a Bill.com connection can enable tax collection at all. A no-op that returns the connection's settings unchanged if it is already enabled and configured. Returns 400 if the connection is not ready for tax calculation. Returns 404 if the connection does not exist, is not a Bill.com connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if provisioning the webhook subscription fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. taxCollectionEnabled (boolean, required) - Whether tax calculation is enabled on this connection. defaultCountry (string) - Default tax country for this connection (ISO 3166-1 alpha-2); `null` when unset. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types this connection syncs. `null` for every non-NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor for this Airwallex connection, as YYYY-MM-DD. `null` for every non-Airwallex connection, or when unset. woocommerceHistoricalSyncStartDate (string) - Import floor for this WooCommerce connection, as YYYY-MM-DD. `null` for every non-WooCommerce connection, or when unset. netsuiteHistoricalSyncStartDate (string) - Import floor for this NetSuite connection, as YYYY-MM-DD. `null` for every non-NetSuite connection, or when unset. microsoftD365HistoricalSyncStartDate (string) - Import floor for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. `null` for every non-D365 connection, or when unset. amazonHistoricalSyncStartDate (string) - Import floor for this Amazon connection, as YYYY-MM-DD. `null` for every non-Amazon connection, or when unset. [truncated, see the reference page] --- # Connect a bunny account POST /connections/bunny/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-bunny-account POST /connections/bunny/connect Connect a bunny account Create a Bunny connection with a client id/secret. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Bunny API call itself fails; retrying may succeed. Category: Connections Request body: subdomain (string, required) - Bunny subdomain, e.g. `mycompany` for mycompany.bunny.com. clientId (string, required) - Bunny API client id. clientSecret (string, required) - Bunny API client secret. name (string) - Custom display name for this connection. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default 7-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Refresh a bunny connection's access token PATCH /connections/bunny/{conn_id}/refresh Source: https://docs.trykintsugi.com/reference/2026-07-21/refresh-a-bunny-connection-s-access-token PATCH /connections/bunny/{conn_id}/refresh Refresh a bunny connection's access token Re-issue a Bunny access token from new (or rotated) client credentials. Returns 400 if the credentials are invalid. Returns 404 if the connection does not exist, is not a Bunny connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if the Bunny API call itself fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: subdomain (string, required) - Bunny subdomain, e.g. `mycompany` for mycompany.bunny.com. clientId (string, required) - Bunny API client id. clientSecret (string, required) - Bunny API client secret. name (string) - Custom display name for this connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Connect a campfire account POST /connections/campfire/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-campfire-account POST /connections/campfire/connect Connect a campfire account Create or update Campfire connections, one per `entityIds` entry. Re-submitting an entity id updates its stored credentials rather than creating a second connection. Returns 400 if the key is invalid or an entity id is not accessible with it. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Campfire API key (Token auth). entityIds (string[], required) - One or many Campfire entity ids; one connection per id. entityNames (string[]) - Display names aligned positionally with `entityIds`. webhookSigningSecret (string) - L2 webhook signing secret shown on Campfire's webhook detail page. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. [truncated, see the reference page] --- # Validate campfire credentials POST /connections/campfire/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-campfire-credentials POST /connections/campfire/validate Validate campfire credentials Probe Campfire `GET /coa/api/entity` with the supplied API key, returning the entities it can access. Returns 400 if the key is invalid or has no accessible entities. Returns 503 if Campfire cannot be reached. Category: Connections Request body: apiKey (string, required) - Campfire API key to probe. Response fields: entities (CampfireValidateEntity[]) - Entities available under the validated key. id (string, required) - Campfire entity id. name (string, required) - Campfire entity display name. currency (string) - Entity base currency. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Update a campfire connection's webhook signing secret PATCH /connections/campfire/{conn_id}/webhook-secret Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-campfire-connection-s-webhook-signing-secret PATCH /connections/campfire/{conn_id}/webhook-secret Update a campfire connection's webhook signing secret Update only the L2 webhook signing secret on an existing Campfire connection. No API-key reprobe; an empty string clears it (back to L1-only). Returns 404 if the connection does not exist, is not a Campfire connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: webhookSigningSecret (string, required) - L2 webhook signing secret shown on Campfire's webhook detail page. An empty string clears it (reverts to L1-only). Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a chargebee account POST /connections/chargebee/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-chargebee-account POST /connections/chargebee/connect Connect a chargebee account Create or update a Chargebee connection for a site, or (with `multipleBusinessEntityEnabled`) one business entity under that site. Re-submitting for the same site (or the same site + business entity) updates the stored key rather than creating a second connection. Returns 400 if the credentials or business entity id are invalid, or if `multipleBusinessEntityEnabled` is true without a `businessEntityId`. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: siteId (string, required) - Chargebee site id. url (string, required) - Chargebee site URL. apiKey (string, required) - Chargebee API key. businessEntityId (string) - Business entity id; required when `multipleBusinessEntityEnabled`. businessEntityName (string) - Business entity display name. multipleBusinessEntityEnabled (boolean) - Connect one business entity rather than the whole site. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR [truncated, see the reference page] --- # Connect a checkoutchamp account POST /connections/checkoutchamp/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-checkoutchamp-account POST /connections/checkoutchamp/connect Connect a checkoutchamp account Create or update a CheckoutChamp connection. Re-submitting the same `loginId` and `campaignId` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. No separate validate route exists for CheckoutChamp. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: loginId (string, required) - CheckoutChamp API login id. password (string, required) - CheckoutChamp API password. campaignId (string) - Optional campaign/store id to filter orders. timezone (string) - IANA timezone for the account's reporting timezone; defaults to America/New_York. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. [truncated, see the reference page] --- # Summarize collected-tax tracking across your connections GET /connections/collecting-summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-collected-tax-tracking-across-your-connections GET /connections/collecting-summary Summarize collected-tax tracking across your connections Per-connection collected-tax tracking counts across every organization your credential can access, or one organization when you send `Organization-Id`. `pendingCount` is registrations not yet confirmed either way; `fixIssuesCount` is registrations confirmed as collecting that were later found not collecting on a transaction. A connection with no tracked registrations is omitted rather than reported with zero counts. Category: Connections Response fields: connectionId (string, required) - Connection id these counts apply to. fixIssuesCount (integer, required) - Registrations confirmed as collecting but later found not collecting on a transaction; needs attention. pendingCount (integer, required) - Registrations not yet confirmed as collecting or not. totalCount (integer, required) - All tracked registrations for this connection, confirmed or not. Response statuses: 200, 400, 401, 403, 404, 422 --- # Start an ebay oauth connect POST /connections/ebay/oauth/authorize-request Source: https://docs.trykintsugi.com/reference/2026-07-21/start-an-ebay-oauth-connect POST /connections/ebay/oauth/authorize-request Start an ebay oauth connect Return the eBay connect URL plus the `state` handle for this attempt. Returns 400 if the platform eBay app is not configured for this environment. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Returns 409 if this browser already has another organization's eBay connect in progress. Category: Connections Request body: historicalSyncStartDate (string) - Import floor chosen before consent, as YYYY-MM-DD. `null` imports all available history. Response fields: authUrl (string, required) - eBay consent URL. state (string, required) - CSRF handle identifying this attempt. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get ebay runame portal urls GET /connections/ebay/oauth/setup Source: https://docs.trykintsugi.com/reference/2026-07-21/get-ebay-runame-portal-urls GET /connections/ebay/oauth/setup Get ebay runame portal urls Return the RuName portal URLs (Auth accepted, Auth declined, privacy policy) for the current Kintsugi environment, to enter into eBay's RuName configuration before connecting. Category: Connections Response fields: authAcceptedUrl (string, required) - eBay Auth Accepted redirect URL. authDeclinedUrl (string, required) - eBay Auth Declined redirect URL. privacyPolicyUrl (string, required) - Privacy policy URL shown to eBay. Response statuses: 200, 400, 401, 403, 404, 422 --- # Start a freshbooks oauth connect POST /connections/freshbooks/oauth/authorize-request Source: https://docs.trykintsugi.com/reference/2026-07-21/start-a-freshbooks-oauth-connect POST /connections/freshbooks/oauth/authorize-request Start a freshbooks oauth connect Return the FreshBooks consent URL for the resolved organization. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Request body: historicalSyncStartDate (string) - Import floor captured at connect time, as YYYY-MM-DD. `null` imports all available history. Response fields: authUrl (string, required) - Consent URL to redirect the user to. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List freshbooks businesses awaiting selection GET /connections/freshbooks/oauth/businesses Source: https://docs.trykintsugi.com/reference/2026-07-21/list-freshbooks-businesses-awaiting-selection GET /connections/freshbooks/oauth/businesses List freshbooks businesses awaiting selection List the businesses under a pending authorization (`selectionKey`, from the OAuth callback) to choose from. Returns 400 if the selection expired or is not this organization's. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Query parameters: selectionKey (string, required) - The selection key returned by the OAuth callback. Response fields: businesses (FreshbooksOAuthBusiness[]) - Businesses available under the pending authorization. accountId (string, required) - FreshBooks account id. businessId (integer) - FreshBooks business id. name (string) - Business display name. identityId (string) - Owning FreshBooks identity id. Response statuses: 200, 400, 401, 403, 404, 422 --- # Finish connecting a freshbooks business POST /connections/freshbooks/oauth/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/finish-connecting-a-freshbooks-business POST /connections/freshbooks/oauth/connect Finish connecting a freshbooks business Create the connection for the business chosen from the businesses list. Returns 400 if the selection has expired, is not this organization's, or `accountId` is not part of it. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: selectionKey (string, required) - Key returned by the OAuth callback. accountId (string, required) - `accountId` of the business chosen from the businesses list. Response fields: success (boolean, required) - Whether the connection was created. message (string) - Human-readable outcome. Response statuses: 200, 400, 401, 403, 404, 422 --- # Enable tax collection on a freshbooks connection POST /connections/freshbooks/{conn_id}/enable-tax Source: https://docs.trykintsugi.com/reference/2026-07-21/enable-tax-collection-on-a-freshbooks-connection POST /connections/freshbooks/{conn_id}/enable-tax Enable tax collection on a freshbooks connection Register FreshBooks Events API webhook callbacks (if needed) and enable tax calculation (L2) on a FreshBooks connection. Unlike the generic enable-tax-collection action, this is required before a FreshBooks connection can enable tax collection at all. Returns 400 if the connection is not ready for tax calculation. Returns 404 if the connection does not exist, is not a FreshBooks connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if registering the webhook callbacks fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Connect a hyperline account POST /connections/hyperline/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-hyperline-account POST /connections/hyperline/connect Connect a hyperline account Create or update a Hyperline connection for one invoicing entity. Re-submitting the same `entityId` updates its stored credentials rather than creating a second connection. Returns 400 if the key or entity is invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Hyperline API key. entityId (string, required) - Hyperline invoicing entity id to connect. companyId (string) - Hyperline company id; required only when the entity has one. entityName (string) - Display name; defaults to the entity's own name. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Validate hyperline credentials POST /connections/hyperline/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-hyperline-credentials POST /connections/hyperline/validate Validate hyperline credentials Probe a Hyperline API key without persisting a connection, returning the companies and invoicing entities available under it for the connect picker. Returns 400 if the key is invalid. Category: Connections Request body: apiKey (string, required) - Hyperline API key to probe. Response fields: entities (HyperlineValidateEntity[]) - Invoicing entities available under the validated key. id (string, required) - Hyperline entity id. name (string, required) - Hyperline entity display name. companyId (string) - Owning company id. timezone (string) - Entity timezone. companies (HyperlineValidateCompany[]) - Companies available under the validated key. id (string, required) - Hyperline company id. name (string, required) - Hyperline company display name. environment (string) - Hyperline environment the key resolved against. Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect a kill bill account POST /connections/killbill/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-kill-bill-account POST /connections/killbill/connect Connect a kill bill account Create or update a Kill Bill connection for a tenant. Re-submitting the same `apiKey` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: baseUrl (string, required) - Kill Bill server base URL. apiKey (string, required) - Kill Bill tenant API key. apiSecret (string, required) - Kill Bill tenant API secret. adminUsername (string) - Kill Bill Basic-auth admin username. adminPassword (string, required) - Kill Bill Basic-auth admin password. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate kill bill credentials POST /connections/killbill/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-kill-bill-credentials POST /connections/killbill/validate Validate kill bill credentials Probe Kill Bill tenant credentials without persisting a connection, returning the resolved tenant id. Returns 400 if authentication fails. Category: Connections Request body: baseUrl (string, required) - Kill Bill server base URL. apiKey (string, required) - Kill Bill tenant API key. apiSecret (string, required) - Kill Bill tenant API secret. adminUsername (string) - Kill Bill Basic-auth admin username. adminPassword (string, required) - Kill Bill Basic-auth admin password. Response fields: tenantId (string) - Kill Bill tenant id resolved by the probe. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update a kill bill connection's HMAC secret PATCH /connections/killbill/{conn_id}/hmac-secret Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-kill-bill-connection-s-hmac-secret PATCH /connections/killbill/{conn_id}/hmac-secret Update a kill bill connection's HMAC secret Update the shared HMAC secret Kill Bill signs inbound tax callbacks with, and push it to the Kill Bill plugin config. An empty string clears L2 verification. Returns 400 if pushing the plugin config fails. Returns 404 if the connection does not exist, is not a Kill Bill connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: hmacSecret (string, required) - HMAC secret. An empty string clears L2 verification. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a maxio account POST /connections/maxio/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-maxio-account POST /connections/maxio/connect Connect a maxio account Create or update a Maxio connection with an API key and subdomain. Re-submitting the same `subdomain` updates its stored key rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Maxio API key. subdomain (string, required) - Maxio account subdomain. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default seven-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Poll an oauth connection-creation status GET /connections/oauth-creation-status/{key} Source: https://docs.trykintsugi.com/reference/2026-07-21/poll-an-oauth-connection-creation-status GET /connections/oauth-creation-status/{key} Poll an oauth connection-creation status Poll the status of an in-progress OAuth connect flow by the opaque `key` its authorize step returned. Served once, then cleared: a repeated poll with the same key after it completes returns 404, as does an unknown or expired key. Requires a valid credential but is not scoped to any organization -- the `key` itself, generated server-side during the authorize step, is what makes this safe to poll without one. Category: Connections Path parameters: key (string, required) - The opaque key returned by the authorize step. Response fields: state (string, required) - Opaque OAuth state the connect flow was started with. message (string, required) - Human-readable status of the in-progress connection. Response statuses: 200, 401, 403, 404, 422 --- # Connect an odoo account POST /connections/odoo/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-an-odoo-account POST /connections/odoo/connect Connect an odoo account Create or update an Odoo connection for a database. Re-submitting the same `database` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: baseUrl (string, required) - Odoo server base URL. database (string, required) - Odoo database name. username (string, required) - Odoo user login. apiKey (string, required) - Odoo API key or password. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default seven-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate odoo credentials POST /connections/odoo/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-odoo-credentials POST /connections/odoo/validate Validate odoo credentials Probe Odoo credentials without persisting a connection, returning the resolved user id. Returns 400 if authentication fails. Category: Connections Request body: baseUrl (string, required) - Odoo server base URL. database (string, required) - Odoo database name. username (string, required) - Odoo user email or login. apiKey (string, required) - Odoo API key or password. Response fields: uid (integer) - Odoo user id resolved by the probe. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update an odoo connection's HMAC secret PATCH /connections/odoo/{conn_id}/hmac-secret Source: https://docs.trykintsugi.com/reference/2026-07-21/update-an-odoo-connection-s-hmac-secret PATCH /connections/odoo/{conn_id}/hmac-secret Update an odoo connection's HMAC secret Update the shared HMAC secret Odoo signs inbound tax callbacks with. An empty string clears L2 verification. Returns 404 if the connection does not exist, is not an Odoo connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: hmacSecret (string, required) - HMAC secret. An empty string clears L2 verification. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a kong konnect metering & billing organization POST /connections/openmeter/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-kong-konnect-metering-billing-organization POST /connections/openmeter/connect Connect a kong konnect metering & billing organization Create or update an OpenMeter connection for one Konnect organization. Re-submitting the same organization id replaces the token and region. Returns 400 when the token is rejected or the organization id does not match the probe. Category: Connections Request body: apiKey (string, required) - Kong Konnect personal access token. region (string, required) - Konnect region: us, eu, au, me, or in. entityId (string, required) - Konnect organization id from validate. entityName (string) - Instance label. Defaults to the Konnect organization name. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Validate a konnect personal access token POST /connections/openmeter/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-a-konnect-personal-access-token POST /connections/openmeter/validate Validate a konnect personal access token Probe a token against one Konnect region without saving a connection. Succeeds only when Metering & Billing returns at least one customer. Category: Connections Request body: apiKey (string, required) - Kong Konnect personal access token to probe. region (string, required) - Konnect region: us, eu, au, me, or in. Response fields: entities (OpenMeterValidateEntity[]) - The Konnect organization available under this token and region. entityId (string, required) - Konnect organization id. entityName (string, required) - Konnect organization name. Response statuses: 200, 400, 401, 403, 404, 422 --- # Read openmeter connection fields for re-auth GET /connections/openmeter/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/read-openmeter-connection-fields-for-re-auth GET /connections/openmeter/{conn_id} Read openmeter connection fields for re-auth Region and instance label for the re-auth dialog. The token is write-only and is not returned. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Connection id. storeName (string) - Instance label. region (string) - Konnect region. externalId (string, required) - Konnect organization id. url (string) - Resolved Metering & Billing base URL. status (PublicConnectionStatusEnum, required) - Connection status. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect an orb account POST /connections/orb/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-an-orb-account POST /connections/orb/connect Connect an orb account Create or update an Orb connection with an API key. `siteName` identifies the Orb account and must be unique per organization; re-submitting the same `siteName` updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or `siteName` is empty. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Orb API key. siteName (string, required) - A name identifying this Orb account; unique per organization. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect an ordway account POST /connections/ordway/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-an-ordway-account POST /connections/ordway/connect Connect an ordway account Create or update an Ordway connection for a user company. Re-submitting the same `userCompany` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: userCompany (string, required) - Ordway company identifier. userEmail (string, required) - Ordway user email. userToken (string, required) - Ordway user token. apiKey (string, required) - Ordway API key. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Generate an ordway webhook secret POST /connections/ordway/{conn_id}/webhook-secret/generate Source: https://docs.trykintsugi.com/reference/2026-07-21/generate-an-ordway-webhook-secret POST /connections/ordway/{conn_id}/webhook-secret/generate Generate an ordway webhook secret Generate (or return the existing) Ordway L2 webhook secret and full webhook URL for registration in Ordway Setup -> Webhooks. Pass `regenerate=true` to rotate an existing secret; the previous secret stops verifying once rotated. Served only from this route: the secret is never returned again on a read. Returns 403 if your credential is not permitted to enable Ordway L2 (a staff-only beta). Returns 404 if the connection does not exist, is not an Ordway connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Query parameters: regenerate (boolean) Response fields: webhookUrl (string, required) - Full webhook URL to register in Ordway. webhookSecret (string, required) - Ordway L2 webhook secret. Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect a plentyone account POST /connections/plentyone/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-plentyone-account POST /connections/plentyone/connect Connect a plentyone account Re-login and create or update a PlentyONE connection for one host PID. Re-submitting the same host updates its stored credentials rather than creating a second connection, and queues a sync. Returns 400 if the credentials or host are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: host (string, required) - PlentyONE system URL or `p{PID}`. username (string, required) - Terra Accounts username. password (string, required) - Store login password. storeName (string) - Display name; defaults to the host's own name. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. marketplaceOrders (string) - How to handle marketplace orders: skip them, or tag and import. allowed values: skip, tag Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. [truncated, see the reference page] --- # Validate plentyone credentials POST /connections/plentyone/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-plentyone-credentials POST /connections/plentyone/validate Validate plentyone credentials Probe a PlentyONE host/username/password without persisting a connection, returning the one synthetic system entity available under them. Returns 400 if authentication or the host fails to resolve. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: host (string, required) - PlentyONE system URL or `p{PID}`. username (string, required) - Terra Accounts username. password (string, required) - Store login password. Response fields: entities (PlentyOneValidateEntity[]) - Systems available under the validated credentials. id (string, required) - Synthetic PlentyONE system entity id (`p{PID}`). name (string, required) - PlentyONE system display name. Response statuses: 200, 400, 401, 403, 404, 422 --- # Disconnect a quickbooks connection POST /connections/quickbooks/disconnect Source: https://docs.trykintsugi.com/reference/2026-07-21/disconnect-a-quickbooks-connection POST /connections/quickbooks/disconnect Disconnect a quickbooks connection Archive the QuickBooks connection matching `realmId` and its transactions; products and customers are archived on a best-effort basis. Searched across every organization your credential owns; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if no active QuickBooks connection matches `realmId` in an organization your credential can reach. Returns 409 if `realmId` matches more than one connection your credential can access; narrow it with a selector. Category: Connections Request body: realmId (string, required) - QuickBooks realm id (company id) to disconnect. Response fields: productsArchived (boolean, required) - Whether the connection's products were archived. `false` means a best-effort step failed and this route should be retried. customersArchived (boolean, required) - Whether the connection's customers were archived. `false` means a best-effort step failed and this route should be retried. Response statuses: 200, 400, 401, 404, 409, 422 --- # Connect a recurly account POST /connections/recurly/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-recurly-account POST /connections/recurly/connect Connect a recurly account Create or update a Recurly connection for one business entity, or the whole site when it has none. Re-submitting the same site (and business entity, when selected) updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or `businessEntityId` is missing when required. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Recurly private API key. businessEntityId (string) - Selected business entity id; required when multiple exist. businessEntityName (string) - Selected business entity display name. businessEntityCode (string) - Selected business entity code. multipleBusinessEntityEnabled (boolean) - Whether the Recurly site supports multiple entities. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. [truncated, see the reference page] --- # Validate recurly credentials POST /connections/recurly/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-recurly-credentials POST /connections/recurly/validate Validate recurly credentials Validate a Recurly API key and list the site's business entities for the connect picker. Returns `multipleBusinessEntityEnabled=false` with no entities when the site has none. Returns 400 if the key is invalid. Category: Connections Request body: apiKey (string, required) - Recurly private API key. Response fields: siteInfo (RecurlySiteInfo, required) - The validated Recurly site. siteId (string, required) - Recurly site id. subdomain (string, required) - Recurly site subdomain. region (string, required) - Recurly region (`us` or `eu`). businessEntities (RecurlyBusinessEntity[]) - Business entities available on this site. id (string, required) - Recurly business entity id. name (string, required) - Recurly business entity display name. code (string, required) - Recurly business entity code. multipleBusinessEntityEnabled (boolean, required) - Whether this Recurly site supports multiple business entities. Response statuses: 200, 400, 401, 403, 404, 422 --- # Connect a rillet account POST /connections/rillet/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-rillet-account POST /connections/rillet/connect Connect a rillet account Create or update a Rillet connection with an API key. Re-submitting the same Rillet subsidiary updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or Rillet's organization/subsidiary info cannot be retrieved. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: apiKey (string, required) - Rillet API key (Bearer token). historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Update a rillet connection's webhook signing token PATCH /connections/rillet/{conn_id}/webhook-token Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-rillet-connection-s-webhook-signing-token PATCH /connections/rillet/{conn_id}/webhook-token Update a rillet connection's webhook signing token Save the Rillet webhook signing token copied from the Rillet dashboard, a prerequisite for enabling L2 tax write-back. Returns 400 if the token is empty. Returns 404 if the connection does not exist, is not a Rillet connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: webhookSigningToken (string, required) - Base64 HMAC secret copied from the Rillet webhook settings. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a shopify account manually POST /connections/shopify/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-shopify-account-manually POST /connections/shopify/connect Connect a shopify account manually Create or update a Shopify connection from a manually entered Admin API access token. Re-submitting the same `shopUrl` updates its stored token rather than creating a second connection. Returns 400 if the credentials are invalid or the store is closed. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: shopUrl (string, required) - Shopify store domain, e.g. `mystore.myshopify.com`. secret (string, required) - Shopify Admin API access token. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Complete a shopify oauth connection POST /connections/shopify/oauth/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/complete-a-shopify-oauth-connection POST /connections/shopify/oauth/connect Complete a shopify oauth connection Complete a Shopify app-installation OAuth flow: looks up the access token the OAuth callback captured for `shopUrl` and creates or updates the connection with it. Re-submitting the same `shopUrl` updates its stored token rather than creating a second connection. Returns 404 if no OAuth-issued access token is found for this shop (the install session expired, or authorize was never completed). Returns 400 if the store is closed, or if `linkState` does not match an unexpired, unused link for this shop. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: shopUrl (string, required) - Shopify store domain, e.g. `mystore.myshopify.com`. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` imports all available history. linkState (string, required) - The one-time link token the Kintsugi app in Shopify Admin issued when the merchant started linking this store. Valid for 10 minutes, for this `shopUrl` only, and once: a connect that then fails because the store is closed still uses it up. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR [truncated, see the reference page] --- # List organizations connected to a shopify store GET /connections/shopify/organizations Source: https://docs.trykintsugi.com/reference/2026-07-21/list-organizations-connected-to-a-shopify-store GET /connections/shopify/organizations List organizations connected to a shopify store List the organizations with an active connection to the Shopify store `shopId`. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Organizations outside your credential's access are never returned. Returns an empty list when none match. Category: Connections Query parameters: shopId (string, required) - The Shopify store id (the `mystore` in `mystore.myshopify.com`). Response fields: organizationId (string, required) - Organization with an active connection to the store. Response statuses: 200, 400, 401, 403, 404, 422 --- # Start a SHOPLINE oauth connect POST /connections/shopline/oauth/authorize Source: https://docs.trykintsugi.com/reference/2026-07-21/start-a-shopline-oauth-connect POST /connections/shopline/oauth/authorize Start a SHOPLINE oauth connect Return the per-store SHOPLINE consent URL for the resolved organization. Returns 400 if `handle` is not a valid SHOPLINE store handle. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Call this from a browser with credentials (cookies) included: the callback that finishes the connect is bound to the session cookie this response sets, so it only completes for the same browser. Category: Connections Request body: handle (string, required) - SHOPLINE store handle. historicalSyncStartDate (string) - Import floor chosen before consent, as YYYY-MM-DD. Persisted on a brand-new connection only; ignored on re-auth. `null` imports all available history. Response fields: authUrl (string, required) - SHOPLINE consent URL. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Connect a stripe account through the stripe app POST /connections/stripe/app-connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-stripe-account-through-the-stripe-app POST /connections/stripe/app-connect Connect a stripe account through the stripe app Create a Stripe connection captured through the Stripe App's OAuth installation flow. Returns 400 if the session is missing or expired. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: accountId (string, required) - Stripe account id captured by the Stripe App installation. mode (PublicStripeAppModeEnum, required) - Stripe environment the app was installed against. allowed values: TEST, LIVE, SANDBOX Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Connect a stripe account POST /connections/stripe/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-stripe-account POST /connections/stripe/connect Connect a stripe account Create or update a Stripe connection with a secret API key. Re-submitting for the same Stripe account updates its stored key rather than creating a second connection. Returns 400 if the key is invalid or Stripe authentication fails. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: publishableKey (string, required) - Stripe publishable key. apiKey (string, required) - Stripe secret key. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Connect a vertex o-series account POST /connections/vertex-o-series/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-vertex-o-series-account POST /connections/vertex-o-series/connect Connect a vertex o-series account Create or update a Vertex O-Series connection for a partition, using either Basic Auth (`username`/`password`) or O Series Cloud OAuth (`clientId`/`clientSecret` + `partitionUuid`). Re-submitting the same `trustedId` updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid, or the auth fields do not form one complete auth mode. No separate validate route exists for Vertex O-Series. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: trustedId (string, required) - Vertex Trusted ID for the partition. username (string) - Integration username (Basic Auth). password (string) - Integration password (Basic Auth). clientId (string) - O Series Cloud OAuth client id. clientSecret (string) - O Series Cloud OAuth client secret. partitionUuid (string) - O Series Cloud partition UUID; required for OAuth connect. reportingClientId (string) - Solution Reporting API client id. reportingClientSecret (string) - Solution Reporting API client secret. backfillStartDate (string) - Optional ISO date (YYYY-MM-DD) for historical backfill. reportDefinitionId (string) - Optional Transaction Detail Extract report definition UUID. soapInstanceUrl (string) - Client Utilities base for Tax Journal sync (SOAP). restInstanceUrl (string) - REST base for health checks (vertex-ws). instanceUrl (string) - Legacy single URL; inferred as SOAP or REST from its shape. name (string) - Display name; defaults to the trusted id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). [truncated, see the reference page] --- # Get a vertex o-series connection's install credentials GET /connections/vertex-o-series/{conn_id}/credentials Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-vertex-o-series-connection-s-install-credentials GET /connections/vertex-o-series/{conn_id}/credentials Get a vertex o-series connection's install credentials Return the Vertex credentials to enter into the external system's Vertex connector (Shopify / NetSuite / Zuora) to complete installation. Allocates a partition from the shared pool on the first call for this connection. Works for a connection of any source that uses Vertex as its tax engine, not only a Vertex O-Series connector connection. Served only from this route; never returned on the generic connection read. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Returns 503 if no partition is currently available. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: customerClientId (string, required) - Vertex customer client id. customerClientSecret (string, required) - Vertex customer client secret. owningPartyCode (string, required) - Vertex Company Code, always `{organizationId}-{connId}`. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Mark a vertex o-series connection as installed POST /connections/vertex-o-series/{conn_id}/mark-installed Source: https://docs.trykintsugi.com/reference/2026-07-21/mark-a-vertex-o-series-connection-as-installed POST /connections/vertex-o-series/{conn_id}/mark-installed Mark a vertex o-series connection as installed Enable Vertex tax calculation on a connection once its external system's Vertex connector is installed, and sync existing registrations. `installationWarnings` lists non-blocking setup issues found along the way. Works for a connection of any source that uses Vertex as its tax engine, not only a Vertex O-Series connector connection. Returns 400 if a NetSuite connection cannot scaffold tax types (tax calculation is disabled again in that case). Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Connect a zenskar account POST /connections/zenskar/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-zenskar-account POST /connections/zenskar/connect Connect a zenskar account Create or update a Zenskar connection. Re-submitting the same `zenskarOrgId` and `apiKey` updates the existing connection rather than creating a second one; a changed `apiKey` creates a new connection (Zenskar's own identity key). Returns 400 if the credentials are invalid. No separate validate route exists for Zenskar. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: zenskarOrgId (string, required) - Zenskar organization id. apiKey (string, required) - Zenskar API key. name (string) - Display name; defaults to the Zenskar org id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Connect a zuora account POST /connections/zuora/connect Source: https://docs.trykintsugi.com/reference/2026-07-21/connect-a-zuora-account POST /connections/zuora/connect Connect a zuora account Create or update a Zuora connection with OAuth client credentials. Multi-Entity tenants select an `entityId` from `POST /connections/zuora/validate` first; single-entity tenants omit it. Re-submitting the same client id (and entity, for Multi-Entity) updates its stored credentials rather than creating a second connection. Returns 400 if the credentials are invalid. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Request body: clientId (string, required) - Zuora OAuth client id. clientSecret (string, required) - Zuora OAuth client secret. baseUrl (string) - Zuora API base URL; defaults to the US production URL. entityId (string) - Zuora entity id (Multi-Entity tenants only). entityName (string) - Zuora entity display name (Multi-Entity tenants only). multiEntityEnabled (boolean) - Whether this tenant is Multi-Entity. historicalSyncStartDate (string) - Import floor for a brand-new connection, as YYYY-MM-DD. Ignored on reconnect. `null` applies the default seven-year lookback. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR [truncated, see the reference page] --- # Validate zuora credentials POST /connections/zuora/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-zuora-credentials POST /connections/zuora/validate Validate zuora credentials Validate Zuora OAuth client credentials and list the tenant's entities for the connect dropdown. Single-entity tenants return `multiEntityEnabled=false` with no entities. Returns 400 if the credentials are invalid. Category: Connections Request body: clientId (string, required) - Zuora OAuth client id. clientSecret (string, required) - Zuora OAuth client secret. baseUrl (string) - Zuora API base URL; defaults to the US production URL. Response fields: multiEntityEnabled (boolean, required) - Whether this Zuora tenant is Multi-Entity. entities (ZuoraEntity[]) - Entities available for a Multi-Entity tenant. id (string, required) - Zuora entity id. name (string, required) - Zuora entity name. displayName (string) - Entity display name. status (string) - Entity status. Response statuses: 200, 400, 401, 403, 404, 422 --- # Save zuora L2 tax setup PATCH /connections/zuora/{conn_id}/tax-setup Source: https://docs.trykintsugi.com/reference/2026-07-21/save-zuora-l2-tax-setup PATCH /connections/zuora/{conn_id}/tax-setup Save zuora L2 tax setup Persist the tenant id and Vertex Connect tax-engine ids on a Zuora connection and register webhook notifications. Enable tax collection with the settings routes afterwards. Returns 400 if `tenantId` or `zuoraVertexTaxEngineId` is empty. Returns 404 if the connection does not exist, is not a Zuora connection, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: tenantId (string, required) - Zuora tenant id. zuoraVertexTaxEngineId (string, required) - Vertex Connect tax engine id. zuoraVertexTaxCompanyId (string) - Vertex Connect tax company id. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. [truncated, see the reference page] --- # Get a connection by id GET /connections/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-connection-by-id GET /connections/{conn_id} Get a connection by id Fetch a single connection by id. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A connection you cannot access and one that does not exist return the same 404, so the API never confirms an id exists. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Delete a connection DELETE /connections/{conn_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/delete-a-connection DELETE /connections/{conn_id} Delete a connection Archive a connection: it stops appearing on every read immediately, and its transactions, products, and customers are archived on a best-effort basis (a partial failure is logged, not surfaced to you). Returns 404 if the connection does not exist, belongs to an organization your credential cannot access, or was already deleted; a second delete is not an idempotent no-op, so repeating it cannot be used to discover that the connection ever existed. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if tearing down the connection's webhook subscription fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response statuses: 204, 400, 401, 403, 404, 422, 503 --- # Activate a connection POST /connections/{conn_id}/activate Source: https://docs.trykintsugi.com/reference/2026-07-21/activate-a-connection POST /connections/{conn_id}/activate Activate a connection Set a connection's status to ACTIVE. A no-op that returns the connection unchanged if it is already ACTIVE. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. Returns 409 if the connection is a Bill.com connection whose external id is already ACTIVE on a different organization. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Record a connection's native-tax-disabled attestation POST /connections/{conn_id}/attest Source: https://docs.trykintsugi.com/reference/2026-07-21/record-a-connection-s-native-tax-disabled-attestation POST /connections/{conn_id}/attest Record a connection's native-tax-disabled attestation Record your confirmation that native tax collection is disabled on the connected platform, satisfying the native-tax L2 readiness check. A new attestation overwrites any prior one. Returns 400 if your credential has no associated email. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: text (string, required) - Verbatim wording of the attestation the customer agreed to. Response fields: isConfirmed (boolean, required) - Whether a native-tax-disabled attestation has been recorded. confirmedBy (string) - Display name (or email) of the confirming user; `null` if unconfirmed. confirmedAt (string) - Timestamp the attestation was recorded; `null` if unconfirmed. text (string) - Verbatim wording the customer agreed to; `null` if unconfirmed. Response statuses: 200, 400, 401, 403, 404, 422 --- # Confirm collected-tax mode for registrations on a connection POST /connections/{conn_id}/confirm-collecting Source: https://docs.trykintsugi.com/reference/2026-07-21/confirm-collected-tax-mode-for-registrations-on-a-connection POST /connections/{conn_id}/confirm-collecting Confirm collected-tax mode for registrations on a connection Confirm collected-tax mode for the given registrations on a connection. Only pending or fix-issues registrations are affected; the rest are ignored. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: registrationIds (string[], required) - Registration ids to confirm as collecting for this connection. Only pending or fix-issues registrations are affected; the rest are ignored. requestId (string) - Optional client-generated id for this confirm attempt (a UUID or a short slug), stored on the audit trail so a later read can tell repeated confirms apart. Response statuses: 204, 400, 401, 403, 404, 422 --- # Deactivate a connection POST /connections/{conn_id}/deactivate Source: https://docs.trykintsugi.com/reference/2026-07-21/deactivate-a-connection POST /connections/{conn_id}/deactivate Deactivate a connection Set a connection's status to INACTIVE. A no-op that returns the connection unchanged if it is already INACTIVE. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if tearing down the connection's webhook subscription fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. minDate (string) - Date of the earliest transaction `GET /transactions` returns for this connection; `null` when it has none. Set by `GET /connections` and `GET /connections/{id}` only; `null` on other responses. [truncated, see the reference page] --- # Disable tax collection on a connection POST /connections/{conn_id}/disable-tax-collection Source: https://docs.trykintsugi.com/reference/2026-07-21/disable-tax-collection-on-a-connection POST /connections/{conn_id}/disable-tax-collection Disable tax collection on a connection Disable tax calculation (L2) on a connection. A no-op that returns the connection's settings unchanged if it is already disabled. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if a per-connector tax-teardown call fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. taxCollectionEnabled (boolean, required) - Whether tax calculation is enabled on this connection. defaultCountry (string) - Default tax country for this connection (ISO 3166-1 alpha-2); `null` when unset. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types this connection syncs. `null` for every non-NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor for this Airwallex connection, as YYYY-MM-DD. `null` for every non-Airwallex connection, or when unset. woocommerceHistoricalSyncStartDate (string) - Import floor for this WooCommerce connection, as YYYY-MM-DD. `null` for every non-WooCommerce connection, or when unset. netsuiteHistoricalSyncStartDate (string) - Import floor for this NetSuite connection, as YYYY-MM-DD. `null` for every non-NetSuite connection, or when unset. microsoftD365HistoricalSyncStartDate (string) - Import floor for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. `null` for every non-D365 connection, or when unset. amazonHistoricalSyncStartDate (string) - Import floor for this Amazon connection, as YYYY-MM-DD. `null` for every non-Amazon connection, or when unset. netsuiteAccountId (string) - NetSuite account id captured from Vault on (re)connect. `null` for every non-NetSuite connection, or when unset. netsuiteSubsidiaryId (string) - NetSuite subsidiary id captured from Vault on (re)connect. `null` for every non-NetSuite connection, or when unset. [truncated, see the reference page] --- # Enable tax collection on a connection POST /connections/{conn_id}/enable-tax-collection Source: https://docs.trykintsugi.com/reference/2026-07-21/enable-tax-collection-on-a-connection POST /connections/{conn_id}/enable-tax-collection Enable tax collection on a connection Enable tax calculation (L2) on a connection. A no-op that returns the connection's settings unchanged if it is already enabled. Returns 400 if the connection is not ready for tax calculation or has opted out of tax collection. Returns 403 if the connection is an Ordway connection your credential is not permitted to enable L2 on. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Returns 503 if a per-connector tax-provisioning call fails; retrying may succeed. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. taxCollectionEnabled (boolean, required) - Whether tax calculation is enabled on this connection. defaultCountry (string) - Default tax country for this connection (ISO 3166-1 alpha-2); `null` when unset. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types this connection syncs. `null` for every non-NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor for this Airwallex connection, as YYYY-MM-DD. `null` for every non-Airwallex connection, or when unset. woocommerceHistoricalSyncStartDate (string) - Import floor for this WooCommerce connection, as YYYY-MM-DD. `null` for every non-WooCommerce connection, or when unset. netsuiteHistoricalSyncStartDate (string) - Import floor for this NetSuite connection, as YYYY-MM-DD. `null` for every non-NetSuite connection, or when unset. microsoftD365HistoricalSyncStartDate (string) - Import floor for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. `null` for every non-D365 connection, or when unset. amazonHistoricalSyncStartDate (string) - Import floor for this Amazon connection, as YYYY-MM-DD. `null` for every non-Amazon connection, or when unset. netsuiteAccountId (string) - NetSuite account id captured from Vault on (re)connect. `null` for every non-NetSuite connection, or when unset. [truncated, see the reference page] --- # Get a connection's L2 enablement readiness GET /connections/{conn_id}/l2-readiness Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-connection-s-l2-enablement-readiness GET /connections/{conn_id}/l2-readiness Get a connection's L2 enablement readiness Aggregate L2 enablement prerequisites (premium entitlement plus the prerequisite checks) for a connection, for the enablement checklist. `checks` is empty when `isPremium` is false. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: connectionId (string, required) - The connection this readiness applies to. isPremium (boolean, required) - Whether the organization is entitled to enable L2 (premium plan or test org). When `false`, `checks` is empty. checks (L2ReadinessCheck[], required) - Every L2 enablement prerequisite check and its current status. id (string, required) - Stable identifier for this prerequisite check. type (PublicL2CheckTypeEnum, required) - Whether this check blocks enablement or only warns. allowed values: REQUIRED, RECOMMENDED status (PublicL2CheckStatusEnum, required) - Whether this check currently passes. allowed values: READY, NOT_READY metadata (L2ReadinessCheckMetadata, required) - Per-check numeric detail used to render progress (e.g. "3 of 5"). count (integer) - Current count for this check, when it applies. total (integer) - Target count for this check, when it applies. capped (boolean) - Whether `count` was capped for cost; render as `N+` when true. attestation (L2Attestation) - Native-tax-disabled attestation state; `null` when unconfirmed. isConfirmed (boolean, required) - Whether a native-tax-disabled attestation has been recorded. confirmedBy (string) - Display name (or email) of the confirming user; `null` if unconfirmed. confirmedAt (string) - Timestamp the attestation was recorded; `null` if unconfirmed. text (string) - Verbatim wording the customer agreed to; `null` if unconfirmed. Response statuses: 200, 400, 401, 403, 404, 422 --- # List a connection's unconfirmed collecting registrations GET /connections/{conn_id}/pending-states Source: https://docs.trykintsugi.com/reference/2026-07-21/list-a-connection-s-unconfirmed-collecting-registrations GET /connections/{conn_id}/pending-states List a connection's unconfirmed collecting registrations List the REGISTERED registrations on this connection awaiting a collected-tax confirmation, for the confirm-collecting modal. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Registration id. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the registration, such as `US`, `CA` or `GB`. stateName (string, required) - Jurisdiction display name. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update a connection's settings PATCH /connections/{conn_id}/settings Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-connection-s-settings PATCH /connections/{conn_id}/settings Update a connection's settings Partially update per-connector settings on a connection: `defaultCountry`, `apideckConnectionState` and `needsUpdate` apply to any connection; every other field applies only to a connection of the matching source (NetSuite, Airwallex, WooCommerce, Microsoft Dynamics 365, Amazon, or DualEntry). Only the fields you send are changed. Returns 400 if `netsuiteSyncMode` selects a cash-capable mode while the NetSuite cash-sale sync beta is off for this connection. Returns 404 if the connection does not exist, belongs to an organization your credential cannot access, or a per-connector field was sent for a connection of a different source. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Request body: defaultCountry (string) - Default tax country to set, as an ISO 3166-1 alpha-2 code. netsuiteSyncMode (PublicNetsuiteSyncModeEnum) - Which NetSuite transaction types to sync. Only valid for a NetSuite connection. allowed values: INVOICE_ONLY, SALES_ORDER_ONLY, SALES_ORDER_AND_INVOICE, CASH_SALE_ONLY, INVOICE_AND_CASH_SALE, ALL airwallexHistoricalSyncStartDate (string) - Import floor to set for this Airwallex connection, as YYYY-MM-DD. Only valid for an Airwallex connection; must not be a future date. woocommerceHistoricalSyncStartDate (string) - Import floor to set for this WooCommerce connection, as YYYY-MM-DD. Only valid for a WooCommerce connection; must not be a future date. netsuiteHistoricalSyncStartDate (string) - Import floor to set for this NetSuite connection, as YYYY-MM-DD. Only valid for a NetSuite connection; must not be a future date. microsoftD365HistoricalSyncStartDate (string) - Import floor to set for this Microsoft Dynamics 365 connection, as YYYY-MM-DD. Only valid for a D365 connection; must not be a future date. amazonHistoricalSyncStartDate (string) - Import floor to set for this Amazon connection, as YYYY-MM-DD. Only valid for an Amazon connection; must not be a future date. netsuiteAccountId (string) - NetSuite account id to set. Only valid for a NetSuite connection. An empty string clears a previously stored id. [truncated, see the reference page] --- # Resync a connection POST /connections/{conn_id}/sync Source: https://docs.trykintsugi.com/reference/2026-07-21/resync-a-connection POST /connections/{conn_id}/sync Resync a connection Manually trigger the same sync a scheduled run performs for a connection. Runs synchronously and may take a while for a connection with many records; the response reflects the connection's state once the sync completes. A no-op that returns the connection unchanged if it is INACTIVE or has a connection error. Returns 400 if the connected platform rejects its stored credentials. Returns 404 if the connection does not exist, is archived, or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: id (string, required) - Kintsugi's unique identifier for the connection. organizationId (string, required) - Id of the organization this connection belongs to. platformEntityId (string) - The platform's own identifier for the entity this connection points at (e.g. a QuickBooks realm id, D365 company id, NetSuite subsidiary id). Use it to resolve a connection from an id you already hold. `null` until captured on (re)connect or backfilled. externalId (string, required) - The connection's own external identifier: an Apideck consumer id for a Vault-backed source, or the platform-specific value the connector stores (e.g. a Shopify shop id, a Stripe publishable key). source (string, required) - Origin platform of the connection (e.g. SHOPIFY, QUICKBOOKS). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) status (PublicConnectionStatusEnum, required) - Lifecycle status of the connection. allowed values: ACTIVE, INACTIVE, CONNECTION_ERROR storeName (string) - Human-readable store or account name for the connection; an empty string when the connection has none. url (string) - Public shop/account URL when the source exposes one; not a secret. createdAt (string, required) - When the connection was created. updatedAt (string) - When the connection was last updated. lastSynced (string) - When this connection last completed a successful sync. [truncated, see the reference page] --- # Archive an archived connection's transactions DELETE /connections/{conn_id}/transactions Source: https://docs.trykintsugi.com/reference/2026-07-21/archive-an-archived-connection-s-transactions DELETE /connections/{conn_id}/transactions Archive an archived connection's transactions Archive the transactions, and best-effort the products and customers, belonging to a connection that has already been archived. Transaction archival may finish asynchronously after this returns; products and customers are archived synchronously. Deleting a connection already triggers this automatically; use this route to retry a prior partial failure. Returns 400 if the connection is not archived. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. A multi-org credential must send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or gets a 400. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: productsArchived (boolean, required) - Whether the connection's products were archived. `false` means a best-effort step failed and this route should be retried. customersArchived (boolean, required) - Whether the connection's customers were archived. `false` means a best-effort step failed and this route should be retried. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get a connection's collected-tax comparison GET /connections/{conn_id}/view-details Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-connection-s-collected-tax-comparison GET /connections/{conn_id}/view-details Get a connection's collected-tax comparison Calculated-vs-collected tax totals for a connection, globally and per jurisdiction, for the collecting drawer. Searched across every organization your credential owns by default; narrow it to one with an `Organization-Id`, `Connection-Id` or `Entity-Id` selector. Returns 404 if the connection does not exist or belongs to an organization your credential cannot access. Category: Connections Path parameters: conn_id (string, required) - The unique identifier of the connection. Response fields: calculatedTaxTotal (string, required) - Sum of `calculatedTax` across every jurisdiction below. collectedTaxTotal (string, required) - Sum of `collectedTax` across every jurisdiction below. jurisdictions (ConnectionCollectingJurisdictionDetail[], required) - Per-registration breakdown; empty when none are tracked. registrationId (string, required) - Registration id. countryCode (string, required) - ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. stateName (string, required) - Jurisdiction display name. dateConfirmed (string) - When collecting was confirmed; `null` if still pending. status (PublicCollectedTaxTrackingStatusEnum, required) - Collected-tax confirmation status for this registration. allowed values: NOT_COLLECTING, CONFIRMED_AND_COLLECTING, CONFIRMED_AND_NOT_COLLECTING, COLLECTING isCollecting (boolean, required) - True when `status` is COLLECTING or CONFIRMED_AND_COLLECTING. hasTaxTxnId (boolean, required) - True when a tax-collected transaction id is recorded. calculatedTax (string, required) - Kintsugi-calculated tax total for this jurisdiction. collectedTax (string, required) - Tax actually collected for this jurisdiction, per source records. Response statuses: 200, 400, 401, 403, 404, 422 --- # List credits GET /credits Source: https://docs.trykintsugi.com/reference/2026-07-21/list-credits GET /credits List credits List credits, keyset-paginated. Covers every organization your credential owns, send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to narrow to one. Filter to one registration's credits with `registrationId`. A cursor is only valid for the filters AND the organization scope it was issued under, including any selector header. Category: Credits Query parameters: registrationId (string) - Return only credits held against this registration. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Credit[], required) - The credits on this page. id (string, required) - Kintsugi's unique identifier for the credit. type (PublicCreditTypeEnum, required) - The kind of credit balance: REFUND, OVERPAYMENT, ITC, or IVT. allowed values: REFUND, OVERPAYMENT, ITC, IVT taxType (PublicTaxTypeEnum, required) - Which tax pool this credit applies to on a combined return. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE amount (string, required) - The credit's face value, as a decimal string. amountConsumed (string, required) - How much of the credit has been applied to filings. amountRemaining (string, required) - How much of the credit is still available. currency (PublicCurrencyEnum) - ISO-4217 currency code of the amounts. Every credit created through this API records one (derived from the registration); `null` appears only on legacy credits created before a currency was stored. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) startDate (string, required) - Date the credit becomes available, as YYYY-MM-DD. endDate (string) - Date the credit expires, as YYYY-MM-DD. `null` when it does not expire. registrationId (string, required) - The registration this credit is held against. organizationId (string, required) - The organization that owns the credit. Always present: a portfolio-wide list spans organizations, so a row is ambiguous without it. ossRegistrationCountryId (string) - The EU OSS member-state enrollment this credit applies to, for an EU OSS registration. `null` otherwise. createdAt (string, required) - When the credit was created, as an RFC-3339 UTC timestamp. [truncated, see the reference page] --- # Create a credit POST /credits Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-credit POST /credits Create a credit Create a credit against a registration in the given organization. `registrationId` is required and must belong to that organization. The credit `type` and `currency` are derived from the registration, an EU OSS registration produces an IVT credit in EUR (and requires `ossRegistrationCountryId`), any other supported jurisdiction produces an ITC credit in the registration country's currency. A credit for an unsupported jurisdiction is rejected. Category: Credits Request body: registrationId (string, required) - The registration to hold the credit against. amount (string, required) - The credit's face value, as a decimal string. ossRegistrationCountryId (string) - The EU OSS member-state enrollment the credit applies to. Required for an EU OSS registration; leave `null` otherwise. endDate (string) - Date the credit expires, as YYYY-MM-DD. `null` for a credit that does not expire. comment (string) - An optional free-text note stored with the credit. Response fields: id (string, required) - Kintsugi's unique identifier for the credit. type (PublicCreditTypeEnum, required) - The kind of credit balance: REFUND, OVERPAYMENT, ITC, or IVT. allowed values: REFUND, OVERPAYMENT, ITC, IVT taxType (PublicTaxTypeEnum, required) - Which tax pool this credit applies to on a combined return. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE amount (string, required) - The credit's face value, as a decimal string. amountConsumed (string, required) - How much of the credit has been applied to filings. amountRemaining (string, required) - How much of the credit is still available. currency (PublicCurrencyEnum) - ISO-4217 currency code of the amounts. Every credit created through this API records one (derived from the registration); `null` appears only on legacy credits created before a currency was stored. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) startDate (string, required) - Date the credit becomes available, as YYYY-MM-DD. endDate (string) - Date the credit expires, as YYYY-MM-DD. `null` when it does not expire. registrationId (string, required) - The registration this credit is held against. [truncated, see the reference page] --- # List customers GET /customers Source: https://docs.trykintsugi.com/reference/2026-07-21/list-customers GET /customers List customers List customers, keyset-paginated. Covers every organization your credential can access; pass an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page; Archived customers are excluded. `hasMore` and `hasPrevious` report whether a page exists that way. A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Customers Query parameters: sort (PublicCustomerSortEnum) - Field to sort by. `createdAt` is the default and is dramatically faster on large organizations; the other keys sort the whole matching set. allowed values: createdAt, name, street1, city, state, postalCode, country, status order (PublicCustomerSortOrder) - Sort direction. Defaults to `desc`, so newest first. allowed values: asc, desc search (string) - Search over customer id, name, email, externalId and externalFriendlyId. id, externalId and externalFriendlyId must match exactly; name and email match a case-insensitive substring. country (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any of them. state (string) - Comma-separated state or province codes; matches any of them. source (string) - Comma-separated source systems; matches any of them. connectionId (string) - Comma-separated connection ids; matches any of them. This filters rows by connection. To restrict which organization is read, send the `Connection-Id` header instead. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Customer[], required) - The customers on this page. id (string, required) - Kintsugi's unique identifier for the customer. organizationId (string, required) - Organization the customer belongs to. Send it as the `Organization-Id` header to scope a write to this customer's organization. externalId (string) - Your stable identifier for the customer. `null` when the source system supplied none. externalFriendlyId (string) - Human-facing identifier from the source system. `null` when the source has only externalId. name (string) - Customer name. [truncated, see the reference page] --- # Create a customer POST /customers Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-customer POST /customers Create a customer Create a customer in the resolved organization. Idempotent on `externalId` and `source`, and additionally on `connectionId` when you send one: sending the same values again returns the existing customer unchanged and responds `200` instead of creating a duplicate. The customer is not updated by this call; use `PATCH /customers/{customerId}` to update. Omitting `connectionId` matches an existing customer with that `externalId` and `source` whatever its connection. If the match is a customer you previously deleted, it is restored (not duplicated) so its transactions and exemptions stay attached to it. A new customer is always `ACTIVE`; delete one with `DELETE`. Category: Customers Request body: externalId (string) - Your stable identifier for the customer, and the key creating is idempotent on. Sending one that already exists for the same source and connection returns that customer unchanged with 200 instead of creating a second one; use PATCH to update it. name (string) - Customer name. companyName (string) - Registered or legal business name, when it differs from name. email (string) - Contact email address. phone (string) - Contact phone number. connectionId (string) - Connection to attribute the customer to. Must belong to the resolved organization. Part of the idempotency key. externalFriendlyId (string) - Human-facing identifier from the source system, shown in place of externalId when the source has both. source (string) - Origin system of the customer (e.g. API, SHOPIFY). Defaults to OTHER. Must be a supported public source; unsupported values are rejected. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) taxRegistrations (CustomerTaxRegistrationWrite[]) - Tax registrations to record for the customer, each keyed by (countryCode, taxType). Repeating a pair in one request is rejected. countryCode (string, required) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Part of the registration's identity: a customer has one registration per (countryCode, taxType) pair. taxType (PublicCustomerTaxTypeEnum, required) - Kind of tax the registration is for. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown [truncated, see the reference page] --- # Get a customer by id GET /customers/{customer_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-customer-by-id GET /customers/{customer_id} Get a customer by id Fetch a single customer by id. Returns 404 if the customer does not exist, is archived, or belongs to an organization your credential cannot access. A customer you cannot access and one that does not exist return the same 404, so the API never confirms an id exists. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Response fields: id (string, required) - Kintsugi's unique identifier for the customer. organizationId (string, required) - Organization the customer belongs to. Send it as the `Organization-Id` header to scope a write to this customer's organization. externalId (string) - Your stable identifier for the customer. `null` when the source system supplied none. externalFriendlyId (string) - Human-facing identifier from the source system. `null` when the source has only externalId. name (string) - Customer name. companyName (string) - Registered or legal business name. email (string) - Contact email address. phone (string) - Contact phone number. status (PublicCustomerStatusEnum, required) - Customer status. Reads never return archived customers, so this is always `ACTIVE`. allowed values: ACTIVE, ARCHIVED addressStatus (PublicCustomerAddressStatusEnum, required) - How far address validation got for this customer. UNVERIFIED until validation has run; BLANK when there is no address to validate. allowed values: UNVERIFIED, INVALID, PARTIALLY_VERIFIED, VERIFIED, UNVERIFIABLE, BLANK registrationNumber (string) - Business registration number, or `null` when Kintsugi has not captured one for this customer. source (string, required) - Origin system of the customer (e.g. API, SHOPIFY). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) connectionId (string) - Connection that produced the customer. `null` when the customer was not produced by a connection (e.g. created through this API). street1 (string) - First line of the street address. An empty string when none was supplied. street2 (string) - Second line of the street address. An empty string when none was supplied. city (string) - City or locality. An empty string when none was supplied. [truncated, see the reference page] --- # Update a customer PATCH /customers/{customer_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-customer PATCH /customers/{customer_id} Update a customer Update a customer in the resolved organization. Only the fields you send are applied. Sending any address field resets `addressStatus` to `UNVERIFIED`; the new address is validated the next time the customer is processed, not during this call. `taxRegistrations` upserts each entry on its `(countryCode, taxType)` pair and leaves unlisted registrations alone; it cannot remove one. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Request body: name (string) - Customer name. Omit to leave unchanged; send a value to replace; send `null` to clear. companyName (string) - Registered or legal business name. Omit to leave unchanged; send a value to replace; send `null` to clear. email (string) - Contact email address. Omit to leave unchanged; send a value to replace; send `null` to clear. phone (string) - Contact phone number. Omit to leave unchanged; send a value to replace; send `null` to clear. street1 (string) - First line of the street address. Omit to leave unchanged; send a value to replace; send `null` to clear. street2 (string) - Second line of the street address. Omit to leave unchanged; send a value to replace; send `null` to clear. city (string) - City or locality. Omit to leave unchanged; send a value to replace; send `null` to clear. county (string) - County or district. Omit to leave unchanged; send a value to replace; send `null` to clear. state (string) - State or province code. Omit to leave unchanged; send a code to replace; send `null` to clear. postalCode (string) - Postal or ZIP code. Omit to leave unchanged; send a value to replace; send `null` to clear. taxRegistrations (CustomerTaxRegistrationWrite[]) - Tax registrations to upsert, each keyed by (countryCode, taxType). Registrations you do not list are left unchanged, and omitting the field touches none. This field cannot remove a registration. countryCode (string, required) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Part of the registration's identity: a customer has one registration per (countryCode, taxType) pair. taxType (PublicCustomerTaxTypeEnum, required) - Kind of tax the registration is for. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown [truncated, see the reference page] --- # Archive a customer DELETE /customers/{customer_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/archive-a-customer DELETE /customers/{customer_id} Archive a customer Delete a customer. It is removed from this API: afterwards it is absent from `GET /customers` and returns 404 from every read and write, exactly as a customer that never existed does. Creating a customer again with the same `externalId` and `source` restores this one instead of making a second, so its transactions and exemptions stay attached to it. Returns 404 if the customer does not exist, is already deleted, or belongs to an organization your credential cannot access. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Upsert a customer tax registration by tax id POST /customers/{customer_id}/tax-registrations Source: https://docs.trykintsugi.com/reference/2026-07-21/upsert-a-customer-tax-registration-by-tax-id POST /customers/{customer_id}/tax-registrations Upsert a customer tax registration by tax id Create or update a tax registration. Send `countryCode` and `taxType` together to validate `taxId` against that pair; omit both to derive from `taxId` and the customer's country. Always `200`. `400` if `taxId` is invalid, mismatched, or only one field is sent. `404` if the customer doesn't exist. Category: Customers Path parameters: customer_id (string, required) - The unique identifier of the customer. Request body: taxId (string, required) - The tax registration number. When countryCode and taxType are both omitted, they are derived from this value together with the customer's own country. countryCode (string) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Send this together with taxType to validate taxId against an explicit pair instead of deriving one. taxType (PublicCustomerTaxTypeEnum) - Kind of tax the registration is for. Send this together with countryCode. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown Response fields: id (string, required) - Kintsugi's unique identifier for the registration. countryCode (string, required) - Country the registration is valid in, as an ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. taxType (PublicCustomerTaxTypeEnum, required) - Kind of tax the registration is for. allowed values: gst, hst, gst_hst, qst, pst, rst, vat, unknown taxId (string, required) - The tax registration number itself. isValid (boolean, required) - Whether the tax id passed validation for its country and type. Derived by Kintsugi; not accepted on write. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Dashboard task counts GET /dashboard/tasks Source: https://docs.trykintsugi.com/reference/2026-07-21/dashboard-task-counts GET /dashboard/tasks Dashboard task counts Counts of registrations, filings, products, addresses, connections, and related work items for the organization selected by Organization-Id, Connection-Id, or Entity-Id. Category: Experience Response fields: registrationsRegimeToChange (integer, required) - Registrations whose tax regime must be updated before filing. registrationsRegimeToAcknowledge (integer, required) - Registrations with a regime change the org has not acknowledged. registrationsToFinish (integer, required) - In-progress registrations that still need setup steps. reviewInternationalExposure (integer) - Jurisdictions with international nexus exposure to review. currentFilingsToApprove (integer, required) - Current-period filings awaiting customer approval. backfilingsToApprove (integer, required) - Back filings awaiting customer approval. pendingProduct (integer, required) - Products missing classification or tax configuration. invalidAddresses (integer, required) - Addresses that failed validation and need correction. blankAddresses (integer, required) - Addresses missing required fields. needsUpdateConnectionsCount (integer, required) - Connections that need reauthorization or configuration updates. expiredExemptionsCount (integer, required) - Customer exemptions that have expired. missingCertificatesCount (integer) - Exemptions missing required certificate documentation. needsTaxCollectionEnableConnectionsCount (integer, required) - Connections where tax collection should be enabled in the source system. readOnlySourcesToEnableTaxCollectionCount (integer, required) - Read-only connections that still need tax collection enabled at the source. iorNumbersToSubmit (integer) - Importer-of-record numbers the org must submit. proposalsToReview (integer) - Pending proposals awaiting accept or decline. Response statuses: 200, 400, 401, 404, 422 --- # List exemption requests GET /exemption-requests Source: https://docs.trykintsugi.com/reference/2026-07-21/list-exemption-requests GET /exemption-requests List exemption requests List exemption requests, newest first. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Optional `status` filters by lifecycle status, and optional `jurisdiction` (a two-letter US state code) returns only requests that include it. Returns an empty list when there are no matching requests. Category: Exemption Requests Query parameters: status (string) - Filter by lifecycle status; returns only requests in that status. jurisdiction (string) - Two-letter US state code. Returns only requests whose jurisdictions include this state. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. allowed values: PENDING, SENT, FAILED expiresAt (string, required) - When the customer's upload link expires, as an RFC-3339 UTC timestamp. createdAt (string, required) - When the request was created, as an RFC-3339 UTC timestamp. [truncated, see the reference page] --- # Create an exemption request POST /exemption-requests Source: https://docs.trykintsugi.com/reference/2026-07-21/create-an-exemption-request POST /exemption-requests Create an exemption request Create an exemption-certificate request in the resolved organization and email the customer at `customerEmail` a link to upload their certificate. `customerId` links the request to a customer in that organization. Returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management. The returned request starts in status `SENT` with every jurisdiction `PENDING_NO_SUBMISSION`. Category: Exemption Requests Request body: customerId (string, required) - Kintsugi customer id to link the request to, in the resolved organization. customerEmail (string, required) - Email address the exemption-request email is sent to. jurisdictions (string[], required) - Uppercase two-letter US state codes the certificate is requested for. notesForCustomer (string) - Optional note included in the email to the customer. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. [truncated, see the reference page] --- # Get pre-send exemption-request conflicts for a customer GET /exemption-requests/conflicts Source: https://docs.trykintsugi.com/reference/2026-07-21/get-pre-send-exemption-request-conflicts-for-a-customer GET /exemption-requests/conflicts Get pre-send exemption-request conflicts for a customer Return per-state warnings for a customer before you create a request: an active certificate, an open request, or an in-review certificate. Non-blocking advice a client can surface before sending. Searched across every organization your credential owns, so no selector is needed for a known customer. Returns an empty list when there are no conflicts, and 404 if the customer does not exist or belongs to an organization your credential cannot access. Category: Exemption Requests Query parameters: customerId (string, required) - The customer to check for conflicts. Response fields: state (string, required) - Two-letter US state code the warnings apply to. warnings (string[], required) - Human-readable warnings for this state (an active certificate, an open request, or an in-review certificate). Non-blocking. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List an exemption request's certificates GET /exemption-requests/{request_id}/certificates Source: https://docs.trykintsugi.com/reference/2026-07-21/list-an-exemption-request-s-certificates GET /exemption-requests/{request_id}/certificates List an exemption request's certificates List the certificates uploaded against one exemption request, newest first. Searched across every organization your credential owns, so no selector is needed for a known request. Returns an empty list when the request has no certificates, and 404 if the request does not exist or belongs to an organization your credential cannot access. Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate document. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the file. reviewStatus (PublicCertificateReviewStatusEnum, required) - Review status of the certificate. allowed values: QUEUED, PROCESSING, UNSUPPORTED, SUGGESTED_REJECT, DUPLICATE, NEEDS_REVIEW, READY_TO_APPROVE, APPROVED, REJECTED uploadedAt (string, required) - When the certificate was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Mark an exemption request completed POST /exemption-requests/{request_id}/mark-completed Source: https://docs.trykintsugi.com/reference/2026-07-21/mark-an-exemption-request-completed POST /exemption-requests/{request_id}/mark-completed Mark an exemption request completed Manually close a request: set its status to `COMPLETED`, record the closure, and immediately expire the customer's upload link. Idempotent — closing an already-completed request returns it unchanged. Returns the updated request. Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. allowed values: PENDING, SENT, FAILED expiresAt (string, required) - When the customer's upload link expires, as an RFC-3339 UTC timestamp. createdAt (string, required) - When the request was created, as an RFC-3339 UTC timestamp. resentAt (string, required) - When the request's upload link was last resent, or null if it has not been resent. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Resend an exemption request's upload link POST /exemption-requests/{request_id}/resend Source: https://docs.trykintsugi.com/reference/2026-07-21/resend-an-exemption-request-s-upload-link POST /exemption-requests/{request_id}/resend Resend an exemption request's upload link Mint a fresh upload link, extend it for another 60 days, email it to the customer, and return the updated request. Allowed once per request, and only while the request is partially completed; the status is unchanged. Send an optional `notesForCustomer` in the body to replace the note in the resend email (a `null` clears it); omit the body to reuse the request's stored note. Returns 409 if the request is ineligible or has already been resent, 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management, and 503 if the email could not be sent (the request is left resendable). Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Request body: notesForCustomer (string) - Optional note to include in the resend email. When present it replaces the request's stored note (send `null` to clear it); omit the field entirely to reuse the note from the original request. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. [truncated, see the reference page] --- # Send an exemption-request reminder POST /exemption-requests/{request_id}/send-reminder Source: https://docs.trykintsugi.com/reference/2026-07-21/send-an-exemption-request-reminder POST /exemption-requests/{request_id}/send-reminder Send an exemption-request reminder Email the customer a reminder for a request that is still awaiting a response, and return the (unchanged) request. The reminder does not change the request's status, expiry, or per-jurisdiction progress. Returns 409 if the request is not in a status that allows a reminder, has expired, or predates regenerable upload links. Returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management, and 503 if the reminder email could not be sent (the request is left unchanged). Category: Exemption Requests Path parameters: request_id (string, required) - The unique identifier of the exemption request. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption request. organizationId (string, required) - Organization the exemption request belongs to. Send it as `Organization-Id` to scope a request to this exemption request. customerId (string, required) - Kintsugi customer id the request is for. customerName (string, required) - Display name of the linked customer, or null when the customer has no name or has been deleted. customerCompanyName (string, required) - Company name of the linked customer, or null when unset. customerEmail (string, required) - Email address the request was sent to. jurisdictions (ExemptionRequestJurisdiction[], required) - Requested states, each with its derived per-jurisdiction progress. state (string, required) - Two-letter US state code the certificate is requested for. chipState (PublicJurisdictionChipStateEnum, required) - Progress of this jurisdiction, derived on read. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED notesForCustomer (string, required) - Note included in the email to the customer, or null when none. status (PublicExemptionRequestStatusEnum, required) - Rolled-up lifecycle status of the request. allowed values: SENT, IN_REVIEW, PARTIALLY_COMPLETED, COMPLETED, REJECTED, CANCELLED emailSendStatus (PublicEmailSendStatusEnum, required) - Delivery status of the request's most recent customer email. allowed values: PENDING, SENT, FAILED expiresAt (string, required) - When the customer's upload link expires, as an RFC-3339 UTC timestamp. [truncated, see the reference page] --- # List exemptions GET /exemptions Source: https://docs.trykintsugi.com/reference/2026-07-21/list-exemptions GET /exemptions List exemptions List exemptions, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Filter to one customer's exemptions with `customerId`, and to a country, jurisdiction, validity start or end date, connection, or a customer name / email substring with the matching parameter. Pass `sort` and `order` to order the list; omit `sort` to keep the default order. `sort=customerName` orders by the owning customer's name. Pass `expand=customer` to embed the owning customer's `companyName` and `customerName` under `customer` on each row. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page; `hasMore` and `hasPrevious` report whether a page exists that way. Archived exemptions are excluded. A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. `expand` does not affect which exemptions are returned, so a cursor stays valid whether or not you pass it. Category: Exemptions Query parameters: sort (PublicExemptionSortEnum) - Field to sort by. Omit to keep the default ordering. `customerName` orders by the owning customer's name, resolved server-side. allowed values: country, jurisdiction, customerName, startDate, endDate, status order (PublicExemptionSortOrder) - Sort direction. Applies only when `sort` is set. Defaults to `asc`. allowed values: asc, desc customerId (string) - Comma-separated customer ids; matches any of them. This is how you read one customer's exemptions. transactionId (string) - Comma-separated transaction ids; matches any of them. status (string) - Comma-separated lifecycle statuses; matches any of them. ARCHIVED is never returned and is rejected here. exemptionType (string) - Comma-separated exemption types; matches any of them. country (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any of them. jurisdiction (string) - State or province code the exemption is scoped to. startDate (string) - Match exemptions whose validity start date is this date. endDate (string) - Match exemptions whose validity end date is this date. search (string) - Match an exact exemption id, or a customer name or email substring. [truncated, see the reference page] --- # Create an exemption POST /exemptions Source: https://docs.trykintsugi.com/reference/2026-07-21/create-an-exemption POST /exemptions Create an exemption Create an exemption in the resolved organization. `customerId` is required and must belong to that organization; so must `transactionId` when you send one. `source` is not accepted on the body: an exemption created through this API is always recorded with source API. ARCHIVED is not an accepted `status` here; an archived exemption is absent from every read on this API. Category: Exemptions Request body: exemptionType (PublicExemptionTypeEnum, required) - What the exemption applies to. allowed values: customer, wholesale, transaction, reverse_charge, partial certificateType (string) - Partial-exemption form code, such as CDTFA-230-M. Required when `exemptionType` is `partial`. Omit it for every other type. startDate (string, required) - First day the exemption is in force, as YYYY-MM-DD. endDate (string) - Last day the exemption is in force, as YYYY-MM-DD. Omit it, or send `null`, for an exemption that does not expire. Must not precede `startDate`. countryCode (string) - ISO 3166-1 alpha-2 country code to scope the exemption to, such as `US`, `CA` or `GB`. An unrecognized code returns 400. jurisdiction (string) - State or province code to scope the exemption to. Validated against `countryCode` when you send both; an unrecognized pair returns 400. reseller (boolean) - Whether the exemption is claimed on the basis of resale. fein (string) - Federal Employer Identification Number to record. salesTaxId (string) - Sales tax registration number to record. status (PublicExemptionWriteStatusEnum) - Lifecycle status to create the exemption with. Defaults to ACTIVE, which is the only status tax calculation applies. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED customerId (string, required) - Customer to hold the exemption against. Must belong to the resolved organization; one that does not returns 400. transactionId (string) - Transaction to apply the exemption to. Must belong to the resolved organization; one that does not returns 400. Omit it to exempt the customer's transactions generally. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption. organizationId (string, required) - Organization the exemption belongs to. Send it as `Organization-Id` to scope a request to this exemption. [truncated, see the reference page] --- # Create many exemptions POST /exemptions/bulk Source: https://docs.trykintsugi.com/reference/2026-07-21/create-many-exemptions POST /exemptions/bulk Create many exemptions Create between 1 and 100 exemptions in the resolved organization in one request. The batch is all-or-nothing: every entry is validated first, and if any one is invalid the whole request returns 400 identifying the offending entry's index and nothing is created. Each entry follows the same rules as `POST /exemptions`: `customerId` is required and must belong to the organization, as must `transactionId` when sent, and `source` is always recorded as API. A `partial` exemption is not accepted here; create it with `POST /exemptions`. An empty list, or more than 100 entries, returns 400. Category: Exemptions Request body: exemptions (ExemptionCreate[], required) - The exemptions to create, between 1 and 100. They are created all-or-nothing: if any one is invalid the whole request fails and none are created. Each entry has the same shape as the body of `POST /exemptions`. exemptionType (PublicExemptionTypeEnum, required) - What the exemption applies to. allowed values: customer, wholesale, transaction, reverse_charge, partial certificateType (string) - Partial-exemption form code, such as CDTFA-230-M. Required when `exemptionType` is `partial`. Omit it for every other type. startDate (string, required) - First day the exemption is in force, as YYYY-MM-DD. endDate (string) - Last day the exemption is in force, as YYYY-MM-DD. Omit it, or send `null`, for an exemption that does not expire. Must not precede `startDate`. countryCode (string) - ISO 3166-1 alpha-2 country code to scope the exemption to, such as `US`, `CA` or `GB`. An unrecognized code returns 400. jurisdiction (string) - State or province code to scope the exemption to. Validated against `countryCode` when you send both; an unrecognized pair returns 400. reseller (boolean) - Whether the exemption is claimed on the basis of resale. fein (string) - Federal Employer Identification Number to record. salesTaxId (string) - Sales tax registration number to record. status (PublicExemptionWriteStatusEnum) - Lifecycle status to create the exemption with. Defaults to ACTIVE, which is the only status tax calculation applies. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED customerId (string, required) - Customer to hold the exemption against. Must belong to the resolved organization; one that does not returns 400. [truncated, see the reference page] --- # List customers missing certificates GET /exemptions/missing-certificates Source: https://docs.trykintsugi.com/reference/2026-07-21/list-customers-missing-certificates GET /exemptions/missing-certificates List customers missing certificates List the customers who hold an active exemption with no certificate on file, keyset-paginated and sorted by exposure (US exempt sales at risk) with an alphabetical tiebreak, highest first. Scoped to one organization: send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, or omit it if your credential owns exactly one. Filter to one state with `jurisdiction`. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page. A cursor is only valid for the `jurisdiction` filter, the `limit`, and the organization it was issued under; change any of those and start from the first page. Category: Exemptions Query parameters: jurisdiction (string) - Filter to one state or province code, e.g. `CA`. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (MissingCertificateCustomer[], required) - The customers on this page, highest exposure first. customerId (string, required) - Kintsugi's unique identifier for the customer. customerName (string) - Customer's name. An empty string when none is on file. customerEmail (string) - Customer's email. An empty string when none is on file, in which case a bulk send skips them (there is nowhere to send the request). uncoveredCount (integer, required) - How many of the customer's active exemptions have no certificate. totalAmount (string, required) - Total exempt sales at risk across the customer's uncertified jurisdictions, as a decimal string. This is the field the list is sorted by, highest first. currency (PublicCurrencyEnum, required) - ISO-4217 currency the exposure amount is in. Always USD: missing-certificate tracking covers US exempt sales only. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) exemptions (MissingCertificateExemption[], required) - The customer's uncertified exemptions. exemptionId (string, required) - Kintsugi's unique identifier for the uncertified exemption. jurisdiction (string) - State or province code the exemption is scoped to. `null` when it covers the whole country. [truncated, see the reference page] --- # Send missing-certificate requests POST /exemptions/missing-certificates/bulk-send Source: https://docs.trykintsugi.com/reference/2026-07-21/send-missing-certificate-requests POST /exemptions/missing-certificates/bulk-send Send missing-certificate requests Email a missing-certificate request to each named customer, bundling all of their uncertified jurisdictions into one request per customer. Scoped to one organization the same way as the list. A customer with no email, or no uncertified exemptions, is skipped and reported in `skippedReasons`. Returns 403 `plan_upgrade_required` when the organization needs a paid plan, or 403 `forbidden` when its plan does not include exemption certificate management. Category: Exemptions Request body: customerIds (string[], required) - Customers to email, between 1 and 100. Each gets one request bundling all of their uncertified jurisdictions. Response fields: sent (integer, required) - How many requests were created and emailed. skipped (integer, required) - How many customers were not sent a request. skippedReasons (MissingCertificateBulkSendSkipped[], required) - One entry per skipped customer. Empty when none were skipped. customerId (string, required) - The customer that was skipped. reason (PublicMissingCertificateSkipReasonEnum, required) - Why the customer was skipped. allowed values: missing_email, no_uncertified_exemptions Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Missing-certificate metrics GET /exemptions/missing-certificates/metrics Source: https://docs.trykintsugi.com/reference/2026-07-21/missing-certificate-metrics GET /exemptions/missing-certificates/metrics Missing-certificate metrics Summarize a single organization's missing-certificate exposure: how many active exemptions lack a certificate, how many active exemptions there are in total, how many customers are affected, and the total US exempt sales at risk. Scoped to one organization the same way as the list. All counts are zero and the amount is `0.00` when nothing is uncertified. Category: Exemptions Response fields: uncoveredCount (integer, required) - Active exemptions with no certificate on file. totalActiveCount (integer, required) - All active exemptions, certified or not. customersAffected (integer, required) - Distinct customers with at least one uncertified exemption. totalAmount (string, required) - Total exempt sales at risk across every uncertified exemption, as a decimal string. currency (PublicCurrencyEnum, required) - ISO-4217 currency the exposure amount is in. Always USD: missing-certificate tracking covers US exempt sales only. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Upload a certificate for a customer POST /exemptions/missing-certificates/{customer_id}/upload Source: https://docs.trykintsugi.com/reference/2026-07-21/upload-a-certificate-for-a-customer POST /exemptions/missing-certificates/{customer_id}/upload Upload a certificate for a customer Upload a certificate on a customer's behalf, as `multipart/form-data` with the file in the `file` part, to cover their uncertified jurisdictions. The file must be a PDF, PNG or JPG and at most 10 MB. Creates one validation job per uncovered exemption and returns 202 with an `uploadSessionId`; poll `GET /exemptions/missing-certificates/{customerId}/upload-status/{uploadSessionId}` for per-jurisdiction results. Scoped to one organization the same way as the list. Returns 404 if the customer has no uncovered exemptions in an organization your credential can access. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan without exemption certificate management is refused with 403 FORBIDDEN. Category: Exemptions Path parameters: customer_id (string, required) - The customer whose uncovered exemptions this upload targets. Response fields: uploadSessionId (string, required) - Poll `GET /exemptions/missing-certificates/{customerId}/upload-status/{uploadSessionId}` with this for per-jurisdiction results. certificateImportIds (string[], required) - One import id per uncovered exemption the upload targets. status (PublicMissingCertificateStatusEnum) - Always PROCESSING at acceptance; poll the status endpoint for results. allowed values: processing, satisfied, rejected Response statuses: 202, 400, 401, 403, 404, 413, 422 --- # Poll a customer's certificate upload status GET /exemptions/missing-certificates/{customer_id}/upload-status/{upload_session_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/poll-a-customer-s-certificate-upload-status GET /exemptions/missing-certificates/{customer_id}/upload-status/{upload_session_id} Poll a customer's certificate upload status Return the per-exemption validation status for a customer's certificate upload session. Each result carries a `reason` when its exemption was rejected. Scoped to one organization the same way as the list. Returns 404 if the upload session does not exist for this customer in an organization your credential can access. Category: Exemptions Path parameters: customer_id (string, required) - The customer whose upload to check. upload_session_id (string, required) - The upload session id returned by the upload endpoint. Response fields: uploadSessionId (string, required) - The upload session these results belong to. status (PublicMissingCertificateStatusEnum, required) - Overall status: PROCESSING while any exemption is still validating, SATISFIED when at least one certificate was accepted, REJECTED otherwise. allowed values: processing, satisfied, rejected reason (string) - Why the whole upload was rejected, such as the certificate matching no uncertified jurisdiction. `null` unless the upload as a whole was rejected. results (MissingCertificateJurisdictionResult[], required) - Per-exemption validation results. certificateImportId (string, required) - Kintsugi's identifier for this exemption's import job. exemptionId (string) - The exemption this result applies to. An empty string when the import could not be matched to one. status (PublicMissingCertificateStatusEnum, required) - Validation status for this exemption. allowed values: processing, satisfied, rejected reason (string) - Why this exemption was rejected. Present only when `status` is REJECTED; `null` otherwise. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get an exemption by id GET /exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-an-exemption-by-id GET /exemptions/{exemption_id} Get an exemption by id Fetch a single exemption by id. Searched across every organization your credential owns, so no selector is needed for a known id. Pass `expand=customer` to embed the owning customer's `companyName` and `customerName` under `customer`. Returns 404 if the exemption does not exist, is archived, or belongs to an organization your credential cannot access, so the API never confirms an id exists. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Query parameters: expand (ExemptionExpand[]) - Relations to embed. Pass `customer` to embed the owning customer's `companyName` and `customerName` under `customer`; omitted otherwise. allowed values: customer Response fields: id (string, required) - Kintsugi's unique identifier for the exemption. organizationId (string, required) - Organization the exemption belongs to. Send it as `Organization-Id` to scope a request to this exemption. customerId (string) - Customer the exemption is held against. `null` for an exemption recorded against a transaction alone. customerName (string) - Display name of the customer the exemption is held against, resolved when you list or fetch an exemption. `null` for an exemption recorded against a transaction alone (no customer). Sort a list by it with `sort=customerName`. transactionId (string) - Transaction the exemption applies to. `null` when it applies to the customer's transactions generally rather than to one of them. exemptionType (PublicExemptionTypeEnum, required) - What the exemption applies to. allowed values: customer, wholesale, transaction, reverse_charge, partial certificateType (string) - Partial-exemption form code, such as CDTFA-230-M. Required when `exemptionType` is `partial`. Null for every other exemption type. status (PublicExemptionStatusEnum, required) - Lifecycle status. Only ACTIVE exemptions are applied by tax calculation; the others are retained for reporting. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED, ARCHIVED countryCode (string) - ISO 3166-1 alpha-2 country code the exemption is scoped to, such as `US`, `CA` or `GB`. `null` when it is not scoped to one country. jurisdiction (string) - State or province code the exemption is scoped to, within `countryCode`. `null` when it covers the whole country. [truncated, see the reference page] --- # Update an exemption PATCH /exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-an-exemption PATCH /exemptions/{exemption_id} Update an exemption Update an exemption in the resolved organization. Only the fields you send are applied; send `endDate` as `null` to remove an expiry. `customerId`, `exemptionType`, `countryCode` and `jurisdiction` cannot be changed, since they define which exemption this is: create a new exemption instead. An exemption that is or becomes ACTIVE has the transactions it covers requeued for tax recalculation, which happens after this call returns. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Request body: startDate (string) - First day the exemption is in force, as YYYY-MM-DD. Omit or send `null` to leave unchanged. endDate (string) - Last day the exemption is in force, as YYYY-MM-DD. Omit to leave unchanged. Send `null` to remove the expiry. Must not precede the exemption's `startDate`. reseller (boolean) - Whether the exemption is claimed on the basis of resale. Omit or send `null` to leave unchanged; send `true` or `false` to replace. fein (string) - Federal Employer Identification Number to record. Omit or send `null` to leave unchanged; send a value to replace. This PATCH cannot clear a stored FEIN. salesTaxId (string) - Sales tax registration number to record. Omit or send `null` to leave unchanged; send a value to replace. This PATCH cannot clear a stored sales tax id. status (PublicExemptionWriteStatusEnum) - Lifecycle status to move the exemption to. Only ACTIVE exemptions are applied by tax calculation. Omit or send `null` to leave unchanged. allowed values: ACTIVE, INACTIVE, EXPIRED, DEACTIVATED requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Kintsugi's unique identifier for the exemption. organizationId (string, required) - Organization the exemption belongs to. Send it as `Organization-Id` to scope a request to this exemption. customerId (string) - Customer the exemption is held against. `null` for an exemption recorded against a transaction alone. customerName (string) - Display name of the customer the exemption is held against, resolved when you list or fetch an exemption. `null` for an exemption recorded against a transaction alone (no customer). Sort a list by it with `sort=customerName`. [truncated, see the reference page] --- # Archive an exemption DELETE /exemptions/{exemption_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/archive-an-exemption DELETE /exemptions/{exemption_id} Archive an exemption Archive an exemption in the resolved organization. Archiving is a soft delete: the exemption is retained but removed from this API, so afterwards it is absent from `GET /exemptions` and returns 404 from every read and write, and it stops being applied by tax calculation. Returns 404 if the exemption does not exist, is already archived, or belongs to an organization your credential cannot access. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Upload an exemption certificate POST /exemptions/{exemption_id}/certificates Source: https://docs.trykintsugi.com/reference/2026-07-21/upload-an-exemption-certificate POST /exemptions/{exemption_id}/certificates Upload an exemption certificate Attach a certificate document to an exemption in the resolved organization, as `multipart/form-data` with the file in the `file` part. The file must be a PDF and at most 10 MB. Returns the stored certificate's metadata; fetch its bytes with `GET /exemptions/{exemptionId}/certificates/{certificateId}`. Returns 404 if the exemption does not exist, is archived, or belongs to an organization your credential cannot access. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate document. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the file. fileSizeBytes (integer, required) - Size of the file in bytes. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422 --- # Download an exemption certificate GET /exemptions/{exemption_id}/certificates/{certificate_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/download-an-exemption-certificate GET /exemptions/{exemption_id}/certificates/{certificate_id} Download an exemption certificate Return a certificate's metadata and a short-lived URL to download its bytes. Searched across every organization your credential owns, so no selector is needed for a known id. Fetch `downloadUrl` directly with a GET; it expires after `expiresInSeconds`. Returns 404 if the exemption or the certificate does not exist, is archived, or belongs to an organization your credential cannot access, or if the certificate is not attached to this exemption. Category: Exemptions Path parameters: exemption_id (string, required) - The unique identifier of the exemption. certificate_id (string, required) - The unique identifier of the certificate document. Response fields: id (string, required) - Kintsugi's unique identifier for the certificate document. fileName (string, required) - Name the file was uploaded under. mimeType (string, required) - Media type of the file. fileSizeBytes (integer, required) - Size of the file in bytes. downloadUrl (string, required) - Time-limited URL to download the certificate bytes. Fetch it directly with a GET; do not send your API credentials to it. It stops working after `expiresInSeconds`, so request this endpoint again for a fresh URL rather than storing it. expiresInSeconds (integer, required) - Seconds from now until `downloadUrl` stops working. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List filings GET /filings Source: https://docs.trykintsugi.com/reference/2026-07-21/list-filings GET /filings List filings List filings, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Every list filter takes a comma-separated list and matches any of the values you send. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor`/`previousCursor` to page. Pass `sort` and `order` to order the list; omit `sort` to keep the default order. None of the sort keys is index-backed, so sorting a large scope sorts the whole matching set. Pass `expand=salesBreakdown`, `expand=vatRecovery` and/or `expand=artifacts` to embed those buckets on each row; omitted otherwise. A cursor is only valid for the sort, the filters AND the organization scope it was issued under; change any of them and start again from the first page. `expand` does not affect which filings are returned, so a cursor stays valid whether or not you pass it. Filings marked do-not-file (skipped under an organization or registration do-not-file setting) are excluded from this list and from the summary counts. Category: Filings Query parameters: expand (FilingExpand[]) - Buckets to embed on each filing. `salesBreakdown` embeds the period's sales composition; `vatRecovery` embeds the EU/UK input-VAT recovery rate pair; `artifacts` embeds the filing's return/payment/additional artifacts by slot. Omitted otherwise. Does not change which filings are returned. allowed values: salesBreakdown, vatRecovery, artifacts limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. sort (PublicFilingSortEnum) - Field to sort by. Omit to keep the default (id-ordered) ordering. allowed values: status, countryCode, stateCode, startDate, endDate, dateFiled, amount, totalTaxLiability order (PublicFilingSortOrder) - Sort direction. Applies only when `sort` is set. Defaults to `asc`. allowed values: asc, desc status (string) - Comma-separated lifecycle statuses; matches any of them. countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any. stateCode (string) - Comma-separated state/province codes; matches any. filingCategory (string) - Comma-separated filing categories; matches any. taxType (string) - Comma-separated tax types; matches any. [truncated, see the reference page] --- # Request back-filings POST /filings/backFilingRequest Source: https://docs.trykintsugi.com/reference/2026-07-21/request-back-filings POST /filings/backFilingRequest Request back-filings Create unapproved BACK_FILING rows for the requested registrations and periods. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization to create them in; the periods must be within the eligible options from `GET /filings/backFilingRequest/options`. Returns 404 when back-filing is not available for the organization or a registration is not visible, 400 when a requested period is invalid or out of bounds, 403 PLAN_UPGRADE_REQUIRED when the organization is on a free plan, and 403 FORBIDDEN when the organization's plan does not include managed filings. Category: Filings Request body: requests (BackFilingRequestRegistrationInput[], required) - The registrations and periods to request back-filings for. registrationId (string, required) - The registration to back-file under. periods (BackFilingRequestPeriodInput[], required) - The periods to back-file, each within the eligible options. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. notes (string) - Optional note recorded on each created filing. Response fields: created (Filing[], required) - The BACK_FILING filings created by this request, unapproved. id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE filingCategory (string, required) - The kind of filing period: REGULAR, AMENDMENT or BACK_FILING (a legacy PREPAYMENT value may appear on historical rows). taxType (PublicTaxTypeEnum, required) - Which taxes this filing covers, from the associated registration. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing jurisdiction, such as `US`, `CA` or `GB`. stateCode (string) - State or province code, or '' for a country-level filing. [truncated, see the reference page] --- # List back-filing request options GET /filings/backFilingRequest/options Source: https://docs.trykintsugi.com/reference/2026-07-21/list-back-filing-request-options GET /filings/backFilingRequest/options List back-filing request options List the registrations and open periods eligible for a customer back-filing request, across every organization your credential owns; send an `Organization-Id` selector to narrow to one. An organization with nothing eligible contributes no registrations rather than failing the read. Category: Filings Response fields: registrations (BackFilingRequestRegistrationOption[]) - Registrations with open back-filing periods across the scope. organizationId (string, required) - Organization the registration belongs to. Present so a portfolio-wide caller can attribute each option to its org. registrationId (string, required) - The eligible registration's id. stateCode (string, required) - The registration's state/jurisdiction code. remittanceTag (string) - P&I remittance timing tag, if known. periods (BackFilingRequestPeriod[]) - The open periods eligible for back-filing. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. label (string, required) - Human-readable period label. helpArticleUrl (string) - Link to the back-filing help article, if any. helpArticleLabel (string) - Label for the help-article link, if any. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get the current back-filing terms GET /filings/backFilingTerms/current Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-current-back-filing-terms GET /filings/backFilingTerms/current Get the current back-filing terms Return the current back-filing terms shown before approving a BACK_FILING. This is global reference data, but a valid credential is still required. Returns 404 when no terms are published. Category: Filings Response fields: id (string, required) - Identifier of the current terms version. version (integer, required) - Monotonic version number of the terms. timeline (string, required) - Timeline copy shown to the customer. penaltiesAndInterest (string, required) - Penalties-and-interest copy shown to the customer. whatYouAreApproving (string, required) - Summary of what approving the terms commits to. fees (string, required) - Fees copy shown to the customer. helpArticleUrl (string) - Link to the help article, if any. helpArticleLabel (string, required) - Label for the help-article link. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Approve filings in bulk POST /filings/bulk/approve Source: https://docs.trykintsugi.com/reference/2026-07-21/approve-filings-in-bulk POST /filings/bulk/approve Approve filings in bulk Approve several filings in one organization. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization they belong to. Returns 200 with a per-filing `successful`/`failed` breakdown even when some filings cannot be approved (unknown id, not an approvable status, or a disabled jurisdiction). Approving BACK_FILING rows with published terms requires `backFilingTermsId`. Returns 403 PLAN_UPGRADE_REQUIRED when the organization is on a free plan, and 403 FORBIDDEN when the organization's plan does not include managed filings. Category: Filings Request body: filingIds (string[], required) - Ids of the filings to approve. Duplicates are ignored. backFilingTermsId (string) - Id of the back-filing terms version accepted for any BACK_FILING. backFilingTermsAcceptedAt (string) - When the customer accepted the back-filing terms (advisory). requestId (string) - Client-minted id for this confirm attempt, stored on the audit row. Response fields: successful (string[], required) - Filing ids acted on, or accepted for a worker when queued. failed (BulkFilingFailure[], required) - Requested filings that were not acted on, each with a reason. id (string, required) - Id of the filing that was not acted on. reason (string, required) - Why this filing was not acted on. queued (boolean) - Whether the batch was enqueued for a worker rather than applied inline. jobId (string) - Reserved for a pollable job handle; null until a job surface exists. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Pause filings in bulk POST /filings/bulk/pause Source: https://docs.trykintsugi.com/reference/2026-07-21/pause-filings-in-bulk POST /filings/bulk/pause Pause filings in bulk Pause several filings in one organization. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization they belong to. `pauseIntent` says why (`review` needs `pausedUntilDate`). Returns 200 with a per-filing `successful`/`failed` breakdown even when some filings cannot be paused; large batches are enqueued and reported with `queued` true. Category: Filings Request body: filingIds (string[], required) - Ids of the filings to pause. Duplicates are ignored. pauseIntent (PublicPauseIntentEnum, required) - Why the filings are being paused. allowed values: review, assistance, skip pausedUntilDate (string) - Date a `review` pause auto-resumes, as YYYY-MM-DD, from today to the 15th of each filing's due month; a filing outside that range is reported in `failed`. Required for `review`; ignored for `assistance` and `skip`. pauseReason (string) - Optional text explaining why the filings are paused. A reason too long for the filing note is rejected with 400. requestId (string) - Client-minted id for this confirm attempt, stored on the audit row. Response fields: successful (string[], required) - Filing ids acted on, or accepted for a worker when queued. failed (BulkFilingFailure[], required) - Requested filings that were not acted on, each with a reason. id (string, required) - Id of the filing that was not acted on. reason (string, required) - Why this filing was not acted on. queued (boolean) - Whether the batch was enqueued for a worker rather than applied inline. jobId (string) - Reserved for a pollable job handle; null until a job surface exists. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List filing jurisdictions GET /filings/jurisdictions Source: https://docs.trykintsugi.com/reference/2026-07-21/list-filing-jurisdictions GET /filings/jurisdictions List filing jurisdictions List the distinct jurisdictions your filings cover, for the list filter. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Returned as distinct state codes followed by the country codes of country-level filings. Category: Filings Response fields: jurisdictions (string[], required) - Distinct state codes, then the country codes of country-level filings, across every organization in scope. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Summarize filings GET /filings/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-filings GET /filings/summary Summarize filings Count filings by lifecycle status and total the scope's tax across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. A status with no filings is omitted rather than reported as zero. Category: Filings Response fields: total (integer, required) - Total filings in scope, across every status. statusCounts (FilingStatusCount[], required) - One entry per status present in scope. A status with no filings is omitted rather than reported as zero. status (PublicFilingStatusEnum, required) - The lifecycle status this count is for. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE count (integer, required) - Number of filings in scope with this status. totalTaxCollected (string, required) - Tax collected across open (UNFILED, FILING or SUBMITTED) filings in scope. totalTaxRemitted (string, required) - Tax remitted across FILED filings in scope. totalTaxCalculated (string, required) - Calculated tax across open (UNFILED, FILING or SUBMITTED) filings in scope. totalTaxLiability (string, required) - Total tax liability across open (UNFILED, FILING or SUBMITTED) filings in scope. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a filing by id GET /filings/{filing_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-filing-by-id GET /filings/{filing_id} Get a filing by id Fetch a single filing by id. Searched across every organization your credential owns, so no selector is needed for a known id. Pass `expand=salesBreakdown`, `expand=vatRecovery` and/or `expand=artifacts` to embed those buckets; omitted otherwise. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: expand (FilingExpand[]) - Buckets to embed on the filing. `salesBreakdown` embeds the period's sales composition; `vatRecovery` embeds the EU/UK input-VAT recovery rate pair; `artifacts` embeds the filing's return/payment/additional artifacts by slot. Omitted otherwise. allowed values: salesBreakdown, vatRecovery, artifacts Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE filingCategory (string, required) - The kind of filing period: REGULAR, AMENDMENT or BACK_FILING (a legacy PREPAYMENT value may appear on historical rows). taxType (PublicTaxTypeEnum, required) - Which taxes this filing covers, from the associated registration. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing jurisdiction, such as `US`, `CA` or `GB`. stateCode (string) - State or province code, or '' for a country-level filing. stateName (string) - Human-readable jurisdiction name. startDate (string, required) - First day of the filing period, as YYYY-MM-DD. endDate (string, required) - Last day of the filing period, as YYYY-MM-DD. dueDate (string) - When the return is due, as YYYY-MM-DD. dateFiled (string) - When the return was filed, as YYYY-MM-DD; null until filed. returnConfirmationId (string) - Return confirmation id from the jurisdiction portal; null until filed. [truncated, see the reference page] --- # Approve a filing POST /filings/{filing_id}/approve Source: https://docs.trykintsugi.com/reference/2026-07-21/approve-a-filing POST /filings/{filing_id}/approve Approve a filing Approve a filing, moving it into the FILING lifecycle and locking its transactions. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. Approving a BACK_FILING with published terms requires `backFilingTermsId`. Pass `autoFile: true` to also turn on the organization's auto-file setting as part of the approval (applied only after it succeeds); omit it to leave the setting unchanged. Approving a filing that is not UNFILED or PAUSED is a no-op and returns the filing unchanged. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if its jurisdiction is not enabled, 403 PLAN_UPGRADE_REQUIRED when the organization is on a free plan, 403 FORBIDDEN when the organization's plan does not include managed filings, and 409 if a filing already exists for the period. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Request body: backFilingTermsId (string) - Id of the back-filing terms version the customer accepted, if any. backFilingTermsAcceptedAt (string) - When the customer accepted the back-filing terms (advisory). requestId (string) - Client-minted id for this confirm attempt, stored on the audit row so a double-submit or retry of one gesture can be collapsed by readers. autoFile (boolean) - When true, also turn on the organization's auto-file setting as part of the approval, so future returns file automatically. Applied only after the approval succeeds; omit, null or false leaves the setting unchanged. No effect for organizations on the new auto-filing experience. Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE [truncated, see the reference page] --- # Upload or replace a filing artifact PUT /filings/{filing_id}/artifacts/{artifact_type} Source: https://docs.trykintsugi.com/reference/2026-07-21/upload-or-replace-a-filing-artifact PUT /filings/{filing_id}/artifacts/{artifact_type} Upload or replace a filing artifact Store a filing's return or payment confirmation document, as `multipart/form-data` with the PDF in the `file` part. `artifactType` picks the slot: `RETURN` or `PAYMENT`. Uploading to a slot that already holds a document replaces it. Only a caller that files the organization's returns itself may upload: a partner with self-managed filings enabled (its portfolio key, or a partner user who can see the organization), or the organization's own ADMIN, OWNER or organization key when such a partner manages it. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization the filing belongs to. The filing's status does not change. Download the stored document through `GET /attachments/{id}/download`. The file must be a PDF of at most 10 MB. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if Kintsugi files the organization's returns or your credential is not its filer, 409 if the filing is not in the FILING, SUBMITTED or FILED status, 413 if the file is too large, and 422 if it is not a PDF. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. artifact_type (PublicFilingArtifactTypeEnum, required) - Which confirmation document the upload fills. allowed values: RETURN, PAYMENT Response fields: id (string, required) - Kintsugi's unique identifier for the attachment. fileName (string, required) - Name the file was uploaded under. contentType (string, required) - Media type of the file. size (integer, required) - Size of the file in bytes. relatedEntity (RelatedEntityRef, required) - The entity this attachment is held against. id (string, required) - Kintsugi's unique identifier for the related entity. type (string, required) - Kind of entity the attachment is held against. uploadedAt (string, required) - When the attachment was uploaded, as an RFC-3339 UTC timestamp. Response statuses: 200, 400, 401, 403, 404, 409, 413, 422, 503 --- # List a filing's deferred transactions GET /filings/{filing_id}/deferredTransactions Source: https://docs.trykintsugi.com/reference/2026-07-21/list-a-filing-s-deferred-transactions GET /filings/{filing_id}/deferredTransactions List a filing's deferred transactions List the transactions deferred out of a filing period, keyset-paginated. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access. A filing type that does not support deferral returns an empty page. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (DeferredTransaction[], required) - The deferred transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. externalId (string) - Your stable identifier for the transaction. `null` when the source system supplied none. date (string) - Transaction date, as an RFC-3339 UTC timestamp. currency (string) - ISO-4217 currency of the amounts. totalAmount (string) - Total transaction amount. totalTaxLiabilityAmount (string) - Total tax liability for the transaction. status (PublicTransactionStatusEnum) - Lifecycle status of the transaction. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID transactionType (PublicTransactionTypeEnum) - Kind of transaction, e.g. SALE or FULL_CREDIT_NOTE. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION description (string) - Free-text description of the transaction, if any. nextCursor (string) - Opaque cursor for the next page. `null` on the last page. previousCursor (string) - Opaque cursor for the previous page. `null` on the first page. hasMore (boolean) - Whether a page exists after this one. hasPrevious (boolean) - Whether a page exists before this one. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a filing's enhanced data GET /filings/{filing_id}/enhanced-data Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-filing-s-enhanced-data GET /filings/{filing_id}/enhanced-data Get a filing's enhanced data Get a US filing's actual tax liability broken down by local jurisdiction. Returns `200` with the data when a current build is stored, and `200` with `FAILED` when the last build failed. Otherwise starts a build and returns `202` with `IN_PROGRESS`; poll until it is `DONE`. A filing with no transactions returns `DONE` with null data. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, and 400 when `jurisdiction` does not match the filing or the state has no enhanced data. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: jurisdiction (string, required) - Two-letter code of the filing's US state, such as `NY`. Must match the filing. Response fields: status (PublicEnhancedFilingDataStatusEnum, required) - `DONE`, `IN_PROGRESS`, or `FAILED`. allowed values: IN_PROGRESS, DONE, FAILED reportId (string) - Id of the stored build, to correlate polls and rebuilds. Null for a filing with no transactions, which has nothing to build. data (EnhancedFilingData) - The enhanced data. Null unless `status` is `DONE`, and null for a `DONE` filing with no transactions. filingId (string, required) - Id of the filing. stateCode (string, required) - Two-letter code of the filing's state. stateName (string, required) - Name of the filing's state. filingPeriod (EnhancedFilingDataPeriod, required) - The period the data covers. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. summary (object, required) - Liability totals for the period. jurisdictionBreakdown (object[], required) - Liability per local jurisdiction. jurisdictionBreakdownGroupedByCounty (object[]) - Liability per jurisdiction grouped by county, for states that report it. deductionsExemptions (object[], required) - Deductions and exemptions taken. transactionRefunds (object[], required) - Refunds that reduce the liability. additionalSummaryFields (object) - State-specific summary fields, if the state has any. additionalBreakdown (object, required) - State-specific breakdowns, keyed by name. useTax (object) - Use tax owed, for states that report it. Response statuses: 200, 202, 400, 401, 403, 404, 409, 422 --- # Rebuild a filing's enhanced data POST /filings/{filing_id}/enhanced-data/rebuild Source: https://docs.trykintsugi.com/reference/2026-07-21/rebuild-a-filing-s-enhanced-data POST /filings/{filing_id}/enhanced-data/rebuild Rebuild a filing's enhanced data Start a new enhanced-data build for a US filing, even when a current one is stored, and return `202` with `IN_PROGRESS`; poll `GET /filings/{filingId}/enhanced-data` until it is `DONE`. A build already in progress is reported instead of starting another. A filing with no transactions returns `200` with `DONE` and null data. Only the organization's own filer can rebuild, as for `PUT /filings/{filingId}/submission`: self-managed filings must be enabled, and a partner member must be assigned to the organization or the organization assigned to no member. Returns 403 otherwise. Allows 10 requests per minute for each portfolio, or for each organization when there is no portfolio; past that it returns `429`. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Query parameters: jurisdiction (string, required) - Two-letter code of the filing's US state, such as `NY`. Must match the filing. Response fields: status (PublicEnhancedFilingDataStatusEnum, required) - `DONE`, `IN_PROGRESS`, or `FAILED`. allowed values: IN_PROGRESS, DONE, FAILED reportId (string) - Id of the stored build, to correlate polls and rebuilds. Null for a filing with no transactions, which has nothing to build. data (EnhancedFilingData) - The enhanced data. Null unless `status` is `DONE`, and null for a `DONE` filing with no transactions. filingId (string, required) - Id of the filing. stateCode (string, required) - Two-letter code of the filing's state. stateName (string, required) - Name of the filing's state. filingPeriod (EnhancedFilingDataPeriod, required) - The period the data covers. startDate (string, required) - First day of the period, as YYYY-MM-DD. endDate (string, required) - Last day of the period, as YYYY-MM-DD. summary (object, required) - Liability totals for the period. jurisdictionBreakdown (object[], required) - Liability per local jurisdiction. jurisdictionBreakdownGroupedByCounty (object[]) - Liability per jurisdiction grouped by county, for states that report it. deductionsExemptions (object[], required) - Deductions and exemptions taken. transactionRefunds (object[], required) - Refunds that reduce the liability. additionalSummaryFields (object) - State-specific summary fields, if the state has any. [truncated, see the reference page] --- # Pause a filing POST /filings/{filing_id}/pause Source: https://docs.trykintsugi.com/reference/2026-07-21/pause-a-filing POST /filings/{filing_id}/pause Pause a filing Pause a filing. Requires an ADMIN or OWNER credential; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. `pauseIntent` says why: `review` auto-resumes on `pausedUntilDate` (which is then required), `assistance` pauses indefinitely for manual help, and `skip` skips the period. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, and 400 if the filing cannot be paused in its current state or the request is invalid for the chosen intent. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Request body: pauseIntent (PublicPauseIntentEnum, required) - Why the filing is being paused. allowed values: review, assistance, skip pausedUntilDate (string) - Date a `review` pause auto-resumes, as YYYY-MM-DD, from today to the 15th of the month the filing is due. Required for `review`; ignored for `assistance` and `skip`. pauseReason (string) - Optional text explaining why the filing is paused. A reason too long for the filing note is rejected with 400. requestId (string) - Client-minted id for this confirm attempt, stored on the audit row so a double-submit or retry of one gesture can be collapsed by readers. Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE filingCategory (string, required) - The kind of filing period: REGULAR, AMENDMENT or BACK_FILING (a legacy PREPAYMENT value may appear on historical rows). taxType (PublicTaxTypeEnum, required) - Which taxes this filing covers, from the associated registration. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing jurisdiction, such as `US`, `CA` or `GB`. [truncated, see the reference page] --- # Recalculate a filing POST /filings/{filing_id}/recalculate Source: https://docs.trykintsugi.com/reference/2026-07-21/recalculate-a-filing POST /filings/{filing_id}/recalculate Recalculate a filing Queue a recalculation of a filing's amounts from its transactions. Only an administrator of a caller that files the organization's returns itself may recalculate: a partner with self-managed filings enabled (its portfolio key, or a partner ADMIN or OWNER), or the organization's own ADMIN, OWNER or organization key, or a reseller key for the portfolio that holds it, when such a partner manages it. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. Returns 202 with `status: QUEUED`; the recalculation runs in the background, so read the filing again for the new amounts. Only US and Canadian filings that are not in FILING, SUBMITTED or FILED status can be recalculated. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if Kintsugi files the organization's returns or your credential is not an administrator of its filer, and 400 if the filing cannot be recalculated. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Response fields: filingId (string, required) - Kintsugi's unique identifier for the filing. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing's jurisdiction. status (PublicFilingRecalculationStatusEnum, required) - `QUEUED` once the recalculation is queued. Poll `GET /filings/{filingId}` for the recalculated amounts. allowed values: QUEUED Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # Submit a filing's confirmation data PUT /filings/{filing_id}/submission Source: https://docs.trykintsugi.com/reference/2026-07-21/submit-a-filing-s-confirmation-data PUT /filings/{filing_id}/submission Submit a filing's confirmation data Save the confirmation data entered for a filing, or mark the filing as filed. Only the organization's own filer can submit, so self-managed filings must be enabled for the organization: a partner credential for its portfolio (a partner member must be assigned to the organization, or the organization must be assigned to no member), or the organization's admin, owner or organization API key. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization the filing belongs to. `action` is `save_draft` to store the data and leave the filing status unchanged, or `mark_filed` to store it and mark the filing filed. A field you omit is left unchanged and a field you send as `null` is cleared. Returns 404 if the filing does not exist or belongs to an organization your credential cannot access, 403 if the credential cannot submit for the organization or self-managed filings are not enabled, and 409 if the filing is not in FILING or SUBMITTED status. Category: Filings Path parameters: filing_id (string, required) - The unique identifier of the filing. Request body: action (PublicFilingSubmissionActionEnum, required) - Save the entered data as a draft, or mark the filing as filed. allowed values: save_draft, mark_filed paymentConfirmationId (string) - The confirmation id the jurisdiction issued for the payment. returnConfirmationId (string) - The confirmation id the jurisdiction issued for the return. amountAdjusted (string) - Manual adjustment to the amount due. amountFees (string) - Fees added to the amount due. amountPenalties (string) - Penalties added to the amount due. amountDiscounts (string) - Discounts applied to the amount due. Response fields: id (string, required) - Kintsugi's unique identifier for the filing. organizationId (string, required) - Organization the filing belongs to. organizationName (string) - Display name of the organization the filing belongs to. `null` when the organization has no name set. registrationId (string) - The registration this filing period is filed under, if any. status (PublicFilingStatusEnum, required) - Lifecycle status of the filing. allowed values: UNFILED, FILED, FILING, SUBMITTED, PAUSED, SKIPPED, CANCELLED, ISSUE [truncated, see the reference page] --- # List imports GET /imports Source: https://docs.trykintsugi.com/reference/2026-07-21/list-imports GET /imports List imports List CSV imports across every organization your credential can access (narrow with a selector), newest first by `createdAt`, keyset-paginated. Archived imports are not listed. Filter with `source` (comma-separated, e.g. `SHOPIFY,STRIPE`). Category: Imports Query parameters: source (string) - Comma-separated import sources to filter by (e.g. SHOPIFY,STRIPE). limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Import[], required) - The results on this page. Empty when there are none. id (string, required) - Import id. organizationId (string, required) - Organization the import belongs to. source (string, required) - Import source (a connector name, or IMPORT for a manual CSV upload). importType (PublicImportTypeEnum, required) - TRANSACTIONS for a sales/purchase CSV, PRODUCT_UPDATES for a product bulk-update workbook. allowed values: TRANSACTIONS, PRODUCT_UPDATES direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file. null when set per row instead (rows default to SALE). allowed values: SALE, PURCHASE fileName (string) - Original uploaded file name. null until known. status (PublicImportStatusEnum, required) - Import processing status. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) rowCount (integer) - Total rows in the uploaded file. null until counted. importedCount (integer) - Rows successfully imported as transactions. skippedCount (integer) - Rows skipped during import. createdAt (string, required) - When the import was created. updatedAt (string) - When the import row last changed. submittedAt (string) - When submit-stage processing started. null until submitted. validationCompletedAt (string) - When validation finished. null until it completes. validationTruncated (boolean) - True when the validation error log was truncated (only the first errors were kept). validRowCount (integer) - Rows that passed validation. null until validation completes. invalidRowCount (integer) - Rows that failed validation. null until validation completes. [truncated, see the reference page] --- # Create an import and get a single-file upload URL POST /imports/initiate Source: https://docs.trykintsugi.com/reference/2026-07-21/create-an-import-and-get-a-single-file-upload-url POST /imports/initiate Create an import and get a single-file upload URL Create an import row for one file and return a presigned URL to PUT its bytes to; check `uploadMode` for how to deliver the file. Set `importType` to `PRODUCT_UPDATES` for a product bulk-update .xlsx workbook. Requires file upload v2 for the target organization. `userId` is required and non-empty with an API key and ignored for signed-in sessions, which record the authenticated user. Category: Imports Request body: fileName (string, required) - Original file name of the upload. size (integer, required) - Declared file size in bytes. contentType (string) - MIME type of the file to upload. source (string, required) - Import source (a connector name, or IMPORT for a manual upload). userId (string) - Required and non-empty when authenticating with an API key: the id of the person or process performing the upload, recorded for audit. Ignored for signed-in sessions, which record the authenticated user. direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file; blank per-row direction cells take this value. allowed values: SALE, PURCHASE importType (PublicImportTypeEnum) - TRANSACTIONS (default) for a sales/purchase CSV. PRODUCT_UPDATES for a product bulk-update workbook: fileName must end in .xlsx and contentType must be the Excel workbook MIME type. allowed values: TRANSACTIONS, PRODUCT_UPDATES Response fields: importId (string, required) - Id of the created import. uploadUrl (string, required) - URL to PUT the file bytes to; a path on this API when uploadMode is local_internal. expiresAt (string, required) - When uploadUrl expires. uploadMode (string, required) - How to deliver the file. `presigned` sends it to the returned URL directly. `local_internal` only appears in local development: send it to the returned path on this API with your credential. allowed values: presigned, local_internal Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Count imports GET /imports/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/count-imports GET /imports/summary Count imports Count imports across every organization your credential can access (portfolio-wide, narrowed with a selector). Archived imports are counted, so `total` can exceed the number of imports `GET /imports` lists. Category: Imports Response fields: total (integer, required) - Total imports in scope, archived imports included. Larger than the number of items `GET /imports` lists when any import is archived. Response statuses: 200, 400, 401, 403, 404, 422 --- # Download a CSV import template GET /imports/template Source: https://docs.trykintsugi.com/reference/2026-07-21/download-a-csv-import-template GET /imports/template Download a CSV import template Download the standard import template with the source column pre-filled. Requires file upload v2 for the target organization. Category: Imports Query parameters: source (string) - Source value to embed in the template (e.g. STRIPE, PROVISION). All sources use the same standard CSV template format. provisionTemplate (string) - For PROVISION only: cash or accrual. format (string) - Download format: csv (default) or xlsx. xlsx is ProVision-only. direction (string) - SALE (default) or PURCHASE. Response statuses: 200, 400, 401, 403, 404, 422 --- # Create upload targets for one or more CSV files POST /imports/upload-urls Source: https://docs.trykintsugi.com/reference/2026-07-21/create-upload-targets-for-one-or-more-csv-files POST /imports/upload-urls Create upload targets for one or more CSV files Create an import row per file and return a presigned S3 POST target for each. Check `uploadMode` for how to deliver the file. Prefer `POST /imports/initiate` for a single file. `userId` is required and non-empty with an API key and ignored for signed-in sessions, which record the authenticated user. Category: Imports Request body: files (ImportUploadFile[], required) - Files to create upload targets for. fileName (string, required) - Name of the file to upload. source (string, required) - Import source the files belong to. userId (string) - Required and non-empty when authenticating with an API key: the id of the person or process performing the upload, recorded for audit. Ignored for signed-in sessions, which record the authenticated user. direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file; blank per-row direction cells take this value. allowed values: SALE, PURCHASE Response fields: fileName (string, required) - Name of the file this target is for. importId (string, required) - Id of the import row created for this file. uploadUrl (string, required) - Where to upload the file: a presigned S3 POST URL, or a path on this API when uploadMode is local_internal. uploadFields (object) - Additional form fields required on the upload POST. uploadMode (string, required) - How to deliver the file. `presigned` sends it to the returned URL directly. `local_internal` only appears in local development: send it to the returned path on this API with your credential. allowed values: presigned, local_internal Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Validate a CSV file POST /imports/validate Source: https://docs.trykintsugi.com/reference/2026-07-21/validate-a-csv-file POST /imports/validate Validate a CSV file Check a CSV file's contents before uploading it. Always answers 200; check `isValid` and `errors` to see whether the file passed. Category: Imports Request body: fileName (string, required) - Name of the file being validated. data (string, required) - Raw CSV file contents. source (string, required) - Import source the file was exported for. direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file; blank per-row direction cells take this value. allowed values: SALE, PURCHASE Response fields: isValid (boolean, required) - True when every row passed validation. fileName (string, required) - Name of the file that was validated. rowCount (integer, required) - Number of data rows found in the file. errors (string[]) - Human-readable validation error messages. Empty when isValid is true. resultData (ImportPreviewRow[]) - Rows that passed validation, parsed and normalized. Empty when the file was rejected outright or every row failed. relatedExternalId (string) - Id of a related transaction, for a credit note row. transactionExternalId (string, required) - Id of the transaction in the source system. status (PublicTransactionStatusEnum, required) - Transaction status in the source system. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID transactionSource (string) - Source of the transaction (a connector name, or IMPORT for a manual CSV upload). date (string, required) - Date the transaction took place. currency (PublicCurrencyEnum, required) - Currency of the transaction. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) description (string) - Description of the transaction. customerId (string, required) - Id of the customer in the source system. taxId (string) - Tax registration number of the customer. customerName (string) - Full name of the customer. customerEmail (string) - Email address of the customer. customerCompanyName (string) - Registered or legal business name of the customer. marketplace (boolean) - True when the transaction was facilitated by a marketplace. shipToPhone (string) - Phone number of the ship-to address. shipToStreetLine1 (string) - First line of the ship-to address. [truncated, see the reference page] --- # Get an import by id GET /imports/{import_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-an-import-by-id GET /imports/{import_id} Get an import by id Fetch a single import by id. Returns 404 if it does not exist or belongs to an organization your credential cannot access. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: id (string, required) - Import id. organizationId (string, required) - Organization the import belongs to. source (string, required) - Import source (a connector name, or IMPORT for a manual CSV upload). importType (PublicImportTypeEnum, required) - TRANSACTIONS for a sales/purchase CSV, PRODUCT_UPDATES for a product bulk-update workbook. allowed values: TRANSACTIONS, PRODUCT_UPDATES direction (PublicTransactionDirectionEnum) - SALE or PURCHASE for the whole file. null when set per row instead (rows default to SALE). allowed values: SALE, PURCHASE fileName (string) - Original uploaded file name. null until known. status (PublicImportStatusEnum, required) - Import processing status. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) rowCount (integer) - Total rows in the uploaded file. null until counted. importedCount (integer) - Rows successfully imported as transactions. skippedCount (integer) - Rows skipped during import. createdAt (string, required) - When the import was created. updatedAt (string) - When the import row last changed. submittedAt (string) - When submit-stage processing started. null until submitted. validationCompletedAt (string) - When validation finished. null until it completes. validationTruncated (boolean) - True when the validation error log was truncated (only the first errors were kept). validRowCount (integer) - Rows that passed validation. null until validation completes. invalidRowCount (integer) - Rows that failed validation. null until validation completes. ingestCompletedAt (string) - When row processing finished. null until it completes. processedRowCount (integer) - Rows processed so far. null when rows are not currently being processed. ingestedRowCount (integer) - Rows imported so far. null when rows are not currently being processed. failedRowCount (integer) - Rows that failed to import so far. null when rows are not currently being processed. [truncated, see the reference page] --- # Get a download link for an import's error artifact GET /imports/{import_id}/error-file Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-download-link-for-an-import-s-error-artifact GET /imports/{import_id}/error-file Get a download link for an import's error artifact Return download instructions for the validation or import error artifact. Pass `phase=import` for row-processing errors; validation errors are the default. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Query parameters: phase (string) - 'validation' (default) or 'import'. Response fields: downloadUrl (string, required) - Presigned URL to download the error artifact. Empty when the bytes are returned inline instead. expiresInSeconds (integer, required) - How long downloadUrl stays valid, in seconds. 0 when downloadUrl is empty. inlineContentBase64 (string) - Base64-encoded error artifact bytes, present only when downloadUrl is empty. Response statuses: 200, 400, 401, 403, 404, 422 --- # Import the validated rows POST /imports/{import_id}/ingest Source: https://docs.trykintsugi.com/reference/2026-07-21/import-the-validated-rows POST /imports/{import_id}/ingest Import the validated rows Import the rows that passed validation. `submitMode` `ALL` requires every row to have passed validation; `VALID_ONLY` imports the rows that passed and skips the rest. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Request body: submitMode (string, required) - ALL requires every row to have passed validation. VALID_ONLY imports the rows that passed and skips the rest. allowed values: ALL, VALID_ONLY idempotencyKey (string, required) - Caller-supplied key so a retried import request does not queue twice. Response fields: importId (string, required) - Id of the import. status (PublicImportStatusEnum, required) - Import processing status after the request. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) Response statuses: 202, 400, 401, 403, 404, 409, 422, 503 --- # Start processing an uploaded import POST /imports/{import_id}/submit Source: https://docs.trykintsugi.com/reference/2026-07-21/start-processing-an-uploaded-import POST /imports/{import_id}/submit Start processing an uploaded import Start submit-stage processing (a malware scan, then validation) for an import created via `initiate`. Answers 202 once queued; an import that already advanced past submit answers 200 with its current status. Category: Imports Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: importId (string, required) - Id of the import. status (PublicImportStatusEnum, required) - Current import processing status. allowed values: NEW, SUBMITTED, VIRUS_SCAN_FAILED, VALIDATION_SUBMIT, VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, IMPORT_STARTED, IMPORTING, FAILURE, SUCCESS, CANCELLED (and 1 more, see the reference page) detail (string, required) - Why submit was a no-op: the import already advanced past the submit stage. Response statuses: 200, 202, 400, 401, 403, 404, 409, 422, 503 --- # List marketplaces GET /marketplaces Source: https://docs.trykintsugi.com/reference/2026-07-21/list-marketplaces GET /marketplaces List marketplaces List marketplace-facilitator registry rows, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `status` defaults to `NO` and `NEEDS_REVIEW` rows; set `includeConfirmed` to see `YES` rows instead. Filter with `sourceTypes` (comma-separated), `sourceNames` (comma-separated), `sourceId` and `connectionId`. Pass `limit` and the opaque `cursor` from a prior response to page. Category: Marketplaces Query parameters: sourceTypes (string) - Comma-separated integration sources; matches any of them. sourceNames (string) - Comma-separated secondary source names to match. sourceId (string) - Substring match on the secondary source id. connectionId (string) - Limit results to marketplaces on this connection. includeConfirmed (boolean) - When true, return `YES` rows instead of `NO` / `NEEDS_REVIEW`. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Marketplace[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for this marketplace registry row. organizationId (string, required) - Organization this marketplace registry belongs to. clientName (string) - Display name of the organization this marketplace belongs to, or `null` when the organization has no name set. connectionId (string) - Connection this marketplace channel is synced through, or `null` when it is not tied to one. sourceId (string) - Secondary source id the connector reported for this channel, or `null` when it reported none. sourceName (string) - Secondary source name the connector reported for this channel (e.g. Amazon, eBay), or `null` when it reported none. sourceType (string) - Integration source that synced this registry row, or `null` when it is not tied to one. status (PublicMarketplaceStatusEnum, required) - Confirmation state: whether transactions matched to this row are treated as marketplace-facilitated sales. allowed values: YES, NO, NEEDS_REVIEW processingStatus (PublicMarketplaceProcessingStatusEnum, required) - Progress of the last change to `status`. allowed values: IDLE, PROCESSING, COMPLETED, FAILED [truncated, see the reference page] --- # Get a marketplace by id GET /marketplaces/{marketplace_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-marketplace-by-id GET /marketplaces/{marketplace_id} Get a marketplace by id Fetch a single marketplace-facilitator registry row by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Response fields: id (string, required) - Kintsugi's unique identifier for this marketplace registry row. organizationId (string, required) - Organization this marketplace registry belongs to. clientName (string) - Display name of the organization this marketplace belongs to, or `null` when the organization has no name set. connectionId (string) - Connection this marketplace channel is synced through, or `null` when it is not tied to one. sourceId (string) - Secondary source id the connector reported for this channel, or `null` when it reported none. sourceName (string) - Secondary source name the connector reported for this channel (e.g. Amazon, eBay), or `null` when it reported none. sourceType (string) - Integration source that synced this registry row, or `null` when it is not tied to one. status (PublicMarketplaceStatusEnum, required) - Confirmation state: whether transactions matched to this row are treated as marketplace-facilitated sales. allowed values: YES, NO, NEEDS_REVIEW processingStatus (PublicMarketplaceProcessingStatusEnum, required) - Progress of the last change to `status`. allowed values: IDLE, PROCESSING, COMPLETED, FAILED transactions (integer, required) - Count of transactions currently matched to this registry row. Response statuses: 200, 400, 401, 403, 404, 422 --- # Update a marketplace's confirmation status PATCH /marketplaces/{marketplace_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-marketplace-s-confirmation-status PATCH /marketplaces/{marketplace_id} Update a marketplace's confirmation status Set a marketplace's confirmation `status`. The update is processed asynchronously: every transaction currently matched to this marketplace is queued to be re-evaluated, and `processingStatus` on the response tracks that job. Returns 409 if a previous change to this marketplace is still processing. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Request body: status (PublicMarketplaceStatusEnum, required) - New confirmation state to set. allowed values: YES, NO, NEEDS_REVIEW requestId (string) - Optional client-generated id for this confirm attempt (a UUID or a short slug), stored on the audit trail so a later read can tell repeated confirms apart. Response fields: id (string, required) - Kintsugi's unique identifier for this marketplace registry row. organizationId (string, required) - Organization this marketplace registry belongs to. clientName (string) - Display name of the organization this marketplace belongs to, or `null` when the organization has no name set. connectionId (string) - Connection this marketplace channel is synced through, or `null` when it is not tied to one. sourceId (string) - Secondary source id the connector reported for this channel, or `null` when it reported none. sourceName (string) - Secondary source name the connector reported for this channel (e.g. Amazon, eBay), or `null` when it reported none. sourceType (string) - Integration source that synced this registry row, or `null` when it is not tied to one. status (PublicMarketplaceStatusEnum, required) - Confirmation state: whether transactions matched to this row are treated as marketplace-facilitated sales. allowed values: YES, NO, NEEDS_REVIEW processingStatus (PublicMarketplaceProcessingStatusEnum, required) - Progress of the last change to `status`. allowed values: IDLE, PROCESSING, COMPLETED, FAILED transactions (integer, required) - Count of transactions currently matched to this registry row. Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # List transactions matched to a marketplace GET /marketplaces/{marketplace_id}/transactions Source: https://docs.trykintsugi.com/reference/2026-07-21/list-transactions-matched-to-a-marketplace GET /marketplaces/{marketplace_id}/transactions List transactions matched to a marketplace List transactions matched to one marketplace, keyset-paginated. Searched across every organization your credential owns, so no selector is needed. Includes transactions with no customer. Newest first unless `orderBy`/`order` say otherwise. Page with `limit` and `cursor`. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Query parameters: orderBy (PublicMarketplaceTransactionSortEnum) - Field to sort by. Omit both `orderBy` and `order` for newest first (`date` descending). Missing values sort last in both directions. allowed values: date, customerName, state, status order (PublicMarketplaceSortOrderEnum) - Sort direction. Defaults to `asc` when `orderBy` or `order` is set alone; `orderBy` defaults to `date`. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (MarketplaceTransaction[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. connectionId (string) - Connection the transaction was synced through. customerId (string) - Kintsugi customer this transaction is attributed to, or `null` when it has none. customerName (string) - Display name of `customerId`, or `null` when it has none. description (string) - Description reported by the source, if any. date (string) - When the transaction occurred. state (string) - Jurisdiction (state/province) code the source reported for this transaction, or `null` when it reported none. amount (string) - Transaction total, before conversion, or `null` when the source reported none. `null` is not zero. convertedAmount (string) - `amount` in the organization's home currency, or `null` when no conversion applied. currency (PublicCurrencyEnum) - ISO-4217 currency `convertedAmount` is expressed in, or `null` when no conversion applied. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) status (PublicTransactionStatusEnum, required) - Settlement state. [truncated, see the reference page] --- # Mark every matched transaction as a marketplace sale POST /marketplaces/{marketplace_id}/transactions/mark-as-marketplace Source: https://docs.trykintsugi.com/reference/2026-07-21/mark-every-matched-transaction-as-a-marketplace-sale POST /marketplaces/{marketplace_id}/transactions/mark-as-marketplace Mark every matched transaction as a marketplace sale Queue every transaction currently matched to this marketplace to be marked as a marketplace-facilitated sale. This runs the same reclassification `status=YES` queues, without changing `status` itself -- use this to re-apply it after new transactions synced. Small batches are applied inline (`queued: false`); larger ones are queued to SQS (`queued: true`) and `status` is unaffected either way. Category: Marketplaces Path parameters: marketplace_id (string, required) - The unique identifier of the marketplace. Response fields: marketplaceId (string, required) - The marketplace this action was run for. queued (boolean, required) - Whether the work was queued to run asynchronously (`true`) or completed before this response returned (`false`, small batches only). Response statuses: 202, 400, 401, 403, 404, 422 --- # List nexus determinations GET /nexus Source: https://docs.trykintsugi.com/reference/2026-07-21/list-nexus-determinations GET /nexus List nexus determinations Returns a keyset page of nexus determinations for organizations your credential owns. Send `Organization-Id`, `Connection-Id`, or `Entity-Id` to narrow to one organization. A cursor is valid only for the filters and organization scope that issued it. Period history is omitted; get a nexus by ID for typed periods. Category: Nexus Query parameters: status (string) - Comma-separated lifecycle statuses. Matches any listed value. countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes. Matches any listed value. stateCode (string) - Comma-separated state or province codes. Matches any listed value. taxType (string) - Comma-separated tax types. Matches any listed value. disregarded (PublicDisregardedFilterEnum) - Which disregard state to return. `CURRENT` returns rows where `isCurrentlyDisregarded` is true; `NONE` returns rows where it is false; `EVER` returns every row that carries a `disregardedAt`, including ones later activity re-exposed. Omit for no disregard filter. allowed values: NONE, CURRENT, EVER collectedTaxNexusMet (boolean) - Filter on whether nexus was met by collecting tax in the jurisdiction. Passing `true` also lifts the default collected-tax-only exclusion, so `collectedTaxOnly` is unnecessary alongside it. collectedTaxOnly (boolean) - Include exposed rows whose only nexus is collected tax. These are hidden by default because collecting tax is not itself an economic or physical exposure. excludeEuEconomicOnly (boolean) - Drop EU member-state rows whose only nexus is economic. Those obligations are represented by the `ZZ_EU` aggregator row, so listing both counts one obligation twice. search (string) - Case-insensitive match on state code or state name. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (NexusSummary[], required) - Nexus rows on this page. id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. [truncated, see the reference page] --- # Export nexus report POST /nexus/reports/export Source: https://docs.trykintsugi.com/reference/2026-07-21/export-nexus-report POST /nexus/reports/export Export nexus report Queue a nexus export for one organization. The report is generated asynchronously and a download link is emailed, so the response is a 202 rather than the file itself. An API-key credential must provide `email`; a first-party bearer session may omit it to send the report to its own account email. Returns 400 if the organization has disabled email delivery. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Nexus Request body: email (string) - Address the generated report download link is emailed to. Required for an API-key credential (it has no session user). For a first-party bearer session it is optional: omit it to send the report to your own account email. Response fields: organizationId (string, required) - Organization the export was queued for. email (string, required) - Address the report download link will be emailed to. Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # Get a nexus determination GET /nexus/{nexus_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-nexus-determination GET /nexus/{nexus_id} Get a nexus determination Returns one nexus determination, including typed period history. Searches every organization your credential owns. Returns 404 if the nexus does not exist or is not visible to your credential. Category: Nexus Path parameters: nexus_id (string, required) Response fields: id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. stateName (string, required) - Display name of the state or province. status (PublicNexusStatusEnum, required) - Lifecycle state of this nexus determination. Ignore unrecognized values. allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED nexusType (PublicNexusTypeEnum, required) - Kind of jurisdiction. `CANADA_FEDERAL` is the wire value for every federal jurisdiction, not only Canada. Ignore unrecognized values. allowed values: CANADA_FEDERAL, EU_AGGREGATOR, EU_IOSS, STATE, EU_MEMBER_STATE taxType (PublicNexusTaxTypeEnum, required) - Tax obligation this row tracks. Sales and use are separate rows. Ignore unrecognized values. allowed values: SALES_TAX, USE_TAX, RETAIL_DELIVERY_FEE salesOrTransactions (PublicSalesOrTransactionsEnum, required) - Volume the jurisdiction counts toward its threshold. Ignore unrecognized values. allowed values: EITHER, SALES, BOTH, TRANSACTIONS periodModel (PublicPeriodModelEnum, required) - How the jurisdiction measures the economic-nexus lookback window. Ignore unrecognized values. allowed values: CURRENT_OR_PREVIOUS, CURRENT_OR_TWO_PREVIOUS, PRECEDING_YEAR_FROM_OCTOBER, CALENDAR_YEAR, PREVIOUS_12_MONTHS, CURRENT_OR_PREVIOUS_12_MONTHS, PREVIOUS_4_QUARTERS, PREVIOUS_4_QUARTERS_OFFSET, PRECEDING_YEAR, PRECEDING_YEAR_QUARTERLY, PRECEDING_YEAR_QUARTERLY_OFFSET currency (string, required) - ISO-4217 currency of the amount fields on this row. [truncated, see the reference page] --- # Disregard a nexus POST /nexus/{nexus_id}/disregard Source: https://docs.trykintsugi.com/reference/2026-07-21/disregard-a-nexus POST /nexus/{nexus_id}/disregard Disregard a nexus Disregard an exposed nexus, moving it off the exposed list. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. The body is optional: omit it to disregard for the ordinary reason, or send `disregardedType` to record an Importer of Record opt-out instead. Returns 404 if the nexus does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Returns 400 if the nexus is not exposed, is already disregarded, or is not eligible for the opt-out you asked for. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Request body: disregardedType (PublicDisregardWriteTypeEnum) - Why the nexus is being disregarded. `DISREGARDED` is a manual disregard. `IOR_OPT_OUT` records that the organization declines to act as Importer of Record for the jurisdiction, and is accepted only when the nexus is `iorOptOutEligible`. Defaults to `DISREGARDED`. allowed values: DISREGARDED, IOR_OPT_OUT requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. stateName (string, required) - Display name of the state or province. status (PublicNexusStatusEnum, required) - Lifecycle state of this nexus determination. Ignore unrecognized values. allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED nexusType (PublicNexusTypeEnum, required) - Kind of jurisdiction. `CANADA_FEDERAL` is the wire value for every federal jurisdiction, not only Canada. Ignore unrecognized values. allowed values: CANADA_FEDERAL, EU_AGGREGATOR, EU_IOSS, STATE, EU_MEMBER_STATE [truncated, see the reference page] --- # List a nexus's exposure history GET /nexus/{nexus_id}/exposure-history Source: https://docs.trykintsugi.com/reference/2026-07-21/list-a-nexus-s-exposure-history GET /nexus/{nexus_id}/exposure-history List a nexus's exposure history List the recorded exposure changes for a nexus, such as its collected tax reaching zero. Searches every organization your credential owns, so no selector is needed for a known id. Returns 404 if the nexus does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. A nexus with no recorded changes returns an empty list. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Response fields: id (string, required) - Opaque unique identifier for this event. eventType (PublicNexusExposureEventTypeEnum, required) - What kind of exposure change this event records. Ignore unrecognized values. allowed values: NET_COLLECTED_TAX_ZEROED_OUT reason (string, required) - Human-readable explanation of why the event was recorded. netTax (string, required) - Net collected tax at the time of the event, as a decimal string. This is `totalCollected` minus `totalRefunded`. totalCollected (string, required) - Total tax collected at the time of the event, as a decimal string. totalRefunded (string, required) - Total tax refunded at the time of the event, as a decimal string. timestamp (string, required) - When the exposure change the event records took effect, as an RFC-3339 UTC timestamp. createdAt (string, required) - When this event row was written, as an RFC-3339 UTC timestamp. state (string, required) - State or province code the event was recorded for. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Resolve a nexus's collected-tax exposure POST /nexus/{nexus_id}/resolve-collected-transactions Source: https://docs.trykintsugi.com/reference/2026-07-21/resolve-a-nexus-s-collected-tax-exposure POST /nexus/{nexus_id}/resolve-collected-transactions Resolve a nexus's collected-tax exposure Clear the collected-tax exposure on a nexus and schedule a recalculation. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. The request body is optional; omit it, or send an empty object, for the default resolve. When present, `requestId` identifies this confirm attempt so duplicate submits of the same gesture can be grouped. Returns 404 if the nexus does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Returns 400 if your credential has no user identity to attribute the resolve to. Category: Nexus Path parameters: nexus_id (string, required) - The unique identifier of the nexus. Request body: requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Opaque unique identifier for this nexus. organizationId (string, required) - Organization this nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. stateName (string, required) - Display name of the state or province. status (PublicNexusStatusEnum, required) - Lifecycle state of this nexus determination. Ignore unrecognized values. allowed values: EXPOSED, APPROACHING, PENDING_REGISTRATION, OSS_PENDING_REGISTRATION, REGISTERED, OSS_REGISTERED, NOT_EXPOSED nexusType (PublicNexusTypeEnum, required) - Kind of jurisdiction. `CANADA_FEDERAL` is the wire value for every federal jurisdiction, not only Canada. Ignore unrecognized values. allowed values: CANADA_FEDERAL, EU_AGGREGATOR, EU_IOSS, STATE, EU_MEMBER_STATE taxType (PublicNexusTaxTypeEnum, required) - Tax obligation this row tracks. Sales and use are separate rows. Ignore unrecognized values. allowed values: SALES_TAX, USE_TAX, RETAIL_DELIVERY_FEE [truncated, see the reference page] --- # Onboarding step completion status GET /onboarding/steps-status Source: https://docs.trykintsugi.com/reference/2026-07-21/onboarding-step-completion-status GET /onboarding/steps-status Onboarding step completion status Which onboarding steps are complete for the organization selected by Organization-Id, Connection-Id, or Entity-Id. Category: Experience Response fields: transactionsStatus (boolean, required) - Whether the org has imported or connected transaction data. physicalNexusStatus (boolean, required) - Whether physical nexus locations are recorded. organizationDetailsStatus (boolean, required) - Whether required organization profile fields are complete. bankDetailsStatus (boolean, required) - Whether payout or remittance bank details are on file. primaryProductsStatus (boolean, required) - Whether primary product categories are configured. planStepStatus (boolean, required) - Whether a billing plan step is complete. onboardingStepsStatus (boolean, required) - Whether all required onboarding steps are complete. autoRegister (boolean, required) - Whether automatic registration is enabled, if configured. autoFile (boolean, required) - Whether automatic filing is enabled, if configured. physicalMailAddressStatus (string, required) - Status of the physical mailing address step, if applicable. accountSetupComplete (boolean) - Sticky flag when account setup gating is satisfied. checklistBranch (string) - Onboarding checklist branch identifier for triage UI. setupPaymentStatus (boolean) - Whether payment setup is complete. mailStepStatus (boolean) - Whether the mail-related onboarding step is complete. ecmStepStatus (boolean) - Whether the exemption certificate management step is complete. analyticsStepStatus (boolean) - Whether the analytics onboarding step is complete. Response statuses: 200, 400, 401, 404, 422 --- # Get organization details GET /organization-details Source: https://docs.trykintsugi.com/reference/2026-07-21/get-organization-details GET /organization-details Get organization details Returns the organization details for the org selected by Organization-Id, Connection-Id, or Entity-Id. Owners and contact SSN/DL are not included. Category: Organizations Response fields: businessDetails (OrganizationDetailsBusinessDetails, required) - Identity and non-address business information. businessName (string) - Legal business name, or null when unset. entityType (PublicEntityTypeEnum) - Legal entity type, or null when unset. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) dba (string) - Doing-business-as name, or null when unset. incorporationState (string) - State or province of incorporation, or null when unset. incorporationCountry (string) - ISO 3166-1 alpha-2 country of incorporation, or null when unset. ein (string) - Employer identification number, or null when unset. businessDescription (string) - Short description of the business, or null when unset. homeStateRegistration (string) - Home-state registration identifier, or null when unset. naics (string) - NAICS industry code, or null when unset. firstOperationsDate (string) - Date the business began operations (YYYY-MM-DD), or null when unset. businessPhone (string) - Primary business phone, or null when unset. businessEmail (string) - Primary business email, or null when unset. businessFiscalYearEnd (string) - Fiscal year end date (YYYY-MM-DD), or null when unset. accountingModel (PublicAccountingModelEnum) - Accounting basis, or null when unset. allowed values: ACCRUAL, CASH addresses (OrganizationDetailsAddresses, required) - Company, business, and mailing addresses. company (OrganizationDetailsCompanyAddress, required) - Legal / company address. address1 (string) - First address line, or null when unset. address2 (string) - Second address line, or null when unset. city (string) - City, or null when unset. state (string) - State or province code, or null when unset. postalCode (string) - Postal or ZIP code, or null when unset. [truncated, see the reference page] --- # Update organization details PATCH /organization-details Source: https://docs.trykintsugi.com/reference/2026-07-21/update-organization-details PATCH /organization-details Update organization details Sectioned upsert of business details, addresses, and contact. Any subset of sections may be sent; absent sections are unchanged. A section that IS present replaces that section as a whole, so send every field you want to keep: the patch granularity is the section, not the field. Creates the details row when missing. Contact SSN/DL and auto-file flags are not accepted. Category: Organizations Request body: businessDetails (BusinessDetailsUpdate) - Identity and non-address business fields. Absent means no change. businessName (string, required) - Legal business name. entityType (PublicEntityTypeEnum, required) - Legal entity type. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) dba (string, required) - Doing-business-as name. incorporationState (string, required) - State or province of incorporation. incorporationCountry (string, required) - ISO 3166-1 alpha-2 country of incorporation. ein (string, required) - Employer identification number. businessDescription (string, required) - Short description of the business. firstOperationsDate (string, required) - Date the business began operations (YYYY-MM-DD). taxId (string) - Incorporation tax id to upsert, or null to leave unchanged. homeStateRegistration (string) - Home-state registration identifier. Omit or send null to leave unchanged; this API does not clear it. naics (string) - NAICS industry code. Omit or send null to leave unchanged; this API does not clear it. businessPhone (string) - Primary business phone. Omit or send null to leave unchanged; this API does not clear it. businessEmail (string) - Primary business email. Omit or send null to leave unchanged; this API does not clear it. businessFiscalYearEnd (string) - Fiscal year end date (YYYY-MM-DD). Omit or send null to leave unchanged; this API does not clear it. accountingModel (PublicAccountingModelEnum) - Accounting basis. Omit or send null to leave unchanged; this API does not clear it. allowed values: ACCRUAL, CASH [truncated, see the reference page] --- # Get organization settings GET /organization-settings Source: https://docs.trykintsugi.com/reference/2026-07-21/get-organization-settings GET /organization-settings Get organization settings Returns the organization settings for the org selected by Organization-Id, Connection-Id, or Entity-Id. Category: Organization Settings Response fields: enableEuRegistration (boolean, required) - Whether EU / OSS registration is enabled for the organization. preferCollectedTaxAmounts (boolean, required) - Whether filings prefer tax amounts collected at the source over Kintsugi-calculated amounts. useSourceProductTaxExempt (boolean, required) - Whether sync respects the source system's product tax-exempt flag instead of Kintsugi classification. allowProductUpdates (boolean, required) - Whether integration-driven product updates are applied. allowAddressUpdates (boolean, required) - Whether integration-driven transaction address updates are applied. enableBusinessAddressFallback (boolean, required) - Whether the business address is used as a fallback when a transaction has no ship-to or bill-to address. autoFile (boolean, required) - Whether eligible filings are submitted automatically. autoRegister (boolean, required) - Whether registrations are opened automatically when nexus is reached. Response statuses: 200, 400, 401, 404, 422 --- # Update organization settings PATCH /organization-settings Source: https://docs.trykintsugi.com/reference/2026-07-21/update-organization-settings PATCH /organization-settings Update organization settings Updates the writable settings. Any subset of fields may be sent; absent fields are unchanged. autoFile / autoRegister require existing organization details. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to change its settings. Category: Organization Settings Request body: enableEuRegistration (boolean) - Whether EU / OSS registration is enabled. Absent means no change. preferCollectedTaxAmounts (boolean) - Whether filings prefer collected tax amounts. Absent means no change. useSourceProductTaxExempt (boolean) - Whether sync respects the source product tax-exempt flag. Absent means no change. allowProductUpdates (boolean) - Whether integration-driven product updates are applied. Absent means no change. allowAddressUpdates (boolean) - Whether integration-driven address updates are applied. Absent means no change. enableBusinessAddressFallback (boolean) - Whether the business address is used as an address fallback. Absent means no change. autoFile (boolean) - Whether eligible filings are submitted automatically. Absent means no change. autoRegister (boolean) - Whether registrations are opened automatically. Absent means no change. requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: enableEuRegistration (boolean, required) - Whether EU / OSS registration is enabled for the organization. preferCollectedTaxAmounts (boolean, required) - Whether filings prefer tax amounts collected at the source over Kintsugi-calculated amounts. useSourceProductTaxExempt (boolean, required) - Whether sync respects the source system's product tax-exempt flag instead of Kintsugi classification. allowProductUpdates (boolean, required) - Whether integration-driven product updates are applied. allowAddressUpdates (boolean, required) - Whether integration-driven transaction address updates are applied. enableBusinessAddressFallback (boolean, required) - Whether the business address is used as a fallback when a transaction has no ship-to or bill-to address. autoFile (boolean, required) - Whether eligible filings are submitted automatically. autoRegister (boolean, required) - Whether registrations are opened automatically when nexus is reached. [truncated, see the reference page] --- # Get exemption-reminder settings GET /organization-settings/exemption-reminders Source: https://docs.trykintsugi.com/reference/2026-07-21/get-exemption-reminder-settings GET /organization-settings/exemption-reminders Get exemption-reminder settings Returns the ECM exemption-reminder settings for the selected organization. Category: Organization Settings Response fields: expiringRemindersEnabled (boolean, required) - Master toggle for expiring-exemption reminders. expiringReminderChips (integer[], required) - Days before expiry to send expiring-exemption reminders. expiringEnabledAt (string) - Server-managed watermark stamped the first time expiring reminders are turned on; null means they never have been. It is not cleared when reminders are turned off, so a non-null value does not mean they are on now — read `expiringRemindersEnabled` for the current state. postExpiryReminderEnabled (boolean, required) - Whether the one-shot post-expiry reminder is enabled. pendingRemindersEnabled (boolean, required) - Master toggle for pending-request reminders. pendingReminderChips (integer[], required) - Days after a request is sent to send pending-request reminders. Response statuses: 200, 400, 401, 404, 422 --- # Update exemption-reminder settings PATCH /organization-settings/exemption-reminders Source: https://docs.trykintsugi.com/reference/2026-07-21/update-exemption-reminder-settings PATCH /organization-settings/exemption-reminders Update exemption-reminder settings Updates the ECM exemption-reminder settings. Any subset of fields may be sent; absent fields are unchanged. The expiring enabledAt watermark is server-managed. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to change its settings. Category: Organization Settings Request body: expiringRemindersEnabled (boolean) - Master toggle for expiring-exemption reminders. Absent means no change. expiringReminderChips (integer[]) - Days before expiry to send reminders. Must contain at least one positive value. postExpiryReminderEnabled (boolean) - Whether the one-shot post-expiry reminder is enabled. Absent means no change. pendingRemindersEnabled (boolean) - Master toggle for pending-request reminders. Absent means no change. pendingReminderChips (integer[]) - Days after a request is sent to send reminders. Must contain at least one positive value. Response fields: expiringRemindersEnabled (boolean, required) - Master toggle for expiring-exemption reminders. expiringReminderChips (integer[], required) - Days before expiry to send expiring-exemption reminders. expiringEnabledAt (string) - Server-managed watermark stamped the first time expiring reminders are turned on; null means they never have been. It is not cleared when reminders are turned off, so a non-null value does not mean they are on now — read `expiringRemindersEnabled` for the current state. postExpiryReminderEnabled (boolean, required) - Whether the one-shot post-expiry reminder is enabled. pendingRemindersEnabled (boolean, required) - Master toggle for pending-request reminders. pendingReminderChips (integer[], required) - Days after a request is sent to send pending-request reminders. Response statuses: 200, 400, 401, 403, 404, 422 --- # List organizations GET /organizations Source: https://docs.trykintsugi.com/reference/2026-07-21/list-organizations GET /organizations List organizations List the organizations your credential can access, keyset-paginated and ordered by name. A portfolio credential lists every organization it owns; narrow to one with an `Organization-Id` selector. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Optionally filter by `search` (name substring) and `status`. Each row is lean by default; pass `include=details` to embed the directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date) under `details` in the same call. Pass `expand=filingMetrics` to embed each organization's filing rollup (total, filed, pending approval, overdue and total liability) under `filingMetrics`. Category: Organizations Query parameters: search (string) - Case-insensitive substring match on the organization name. status (PublicOrganizationStatusEnum) - Filter to organizations with this status. allowed values: ACTIVE, ARCHIVED include (OrganizationInclude[]) - Optional expansions to embed on each row. Pass `details` to include the directory-detail fields under `details`; omitted otherwise. allowed values: details expand (OrganizationExpand[]) - Optional computed values to embed on each row. Pass `filingMetrics` to include the filing rollup under `filingMetrics`; omitted otherwise. allowed values: filingMetrics limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (OrganizationListItem[], required) - Organizations on this page, in the page's sort order (name). id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string, required) - Company state. Empty string if unset. [truncated, see the reference page] --- # Create an organization POST /organizations Source: https://docs.trykintsugi.com/reference/2026-07-21/create-an-organization POST /organizations Create an organization Create a new organization. A portfolio credential links the new organization to its portfolio, so it enters that credential's scope. Admin or Owner only: returns 403 if your credential belongs to the portfolio but is not permitted to create organizations in it. Returns the created organization. Category: Organizations Request body: name (string, required) - Display name of the organization. isTest (boolean) - Whether this is a test organization. Defaults to false. A portfolio-authenticated create under a test partner always persists a test organization, even if this is false. A user-session create still honors the submitted flag. billingMode (PublicBillingMode) - How the new client is billed under the portfolio. Portfolio credentials only. Ignored when the portfolio already has a billing type (the client inherits it) and for a test portfolio. allowed values: PARTNER_MANAGED, CLIENT_MANAGED businessWebsites (string[]) - Company or storefront website URLs for the new client. Portfolio credentials only. At most 10 unique URLs. A URL without a scheme is stored as https. Duplicates are dropped. Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string, required) - Company state. Empty string if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) [truncated, see the reference page] --- # Summarize your organizations GET /organizations/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-your-organizations GET /organizations/summary Summarize your organizations Aggregate counts across every organization your credential can access: the total, how many are active, and how many distinct NAICS industries they span. Category: Organizations Response fields: total (integer, required) - Total number of organizations you can access. active (integer, required) - Number of those organizations that are active. industries (integer, required) - Number of distinct NAICS industries across those organizations. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get an organization by id GET /organizations/{org_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-an-organization-by-id GET /organizations/{org_id} Get an organization by id Fetch a single organization by id. Returns 404 if the organization does not exist or your credential cannot access it. An organization you cannot access and one that does not exist return the same 404, so the API never confirms an id exists. Lean by default; pass `include=details` to embed the directory-detail fields under `details`. Category: Organizations Path parameters: org_id (string, required) - The unique identifier of the organization. Query parameters: include (OrganizationInclude[]) - Optional expansions to embed. Pass `details` to include the directory-detail fields under `details`; omitted otherwise. allowed values: details Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string, required) - Company state. Empty string if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) einMasked (string, required) - Employer Identification Number with all but the last four digits masked, or null if no EIN is on file. industry (string, required) - NAICS industry code, or null if not captured. primaryContactName (string, required) - Business contact name. Empty string if unset. primaryContactEmail (string, required) - Business contact email. Empty string if unset. [truncated, see the reference page] --- # Update an organization PATCH /organizations/{org_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-an-organization PATCH /organizations/{org_id} Update an organization Update an organization's name. Address and business-profile fields are updated through `PATCH /organization-details`. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to change it. Returns 404 if the organization does not exist or your credential cannot access it. Category: Organizations Path parameters: org_id (string, required) - The unique identifier of the organization. Request body: name (string, required) - New display name for the organization. Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string, required) - Company state. Empty string if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) einMasked (string, required) - Employer Identification Number with all but the last four digits masked, or null if no EIN is on file. industry (string, required) - NAICS industry code, or null if not captured. primaryContactName (string, required) - Business contact name. Empty string if unset. primaryContactEmail (string, required) - Business contact email. Empty string if unset. registeredStates (integer, required) - Number of states the organization has registrations in. clientSince (string, required) - When the organization joined the portfolio, or null if it is not linked to a portfolio. [truncated, see the reference page] --- # Archive an organization POST /organizations/{org_id}/archive Source: https://docs.trykintsugi.com/reference/2026-07-21/archive-an-organization POST /organizations/{org_id}/archive Archive an organization Archive an organization, capturing a churn reason. This cascades: connections are archived, API keys deleted, and any billing subscription cancelled. `notes` is required when `reason` is OTHER. Admin or Owner only: returns 403 if your credential may read the organization but is not permitted to archive it. Returns 404 if the organization does not exist or your credential cannot access it. Category: Organizations Path parameters: org_id (string, required) - The unique identifier of the organization. Request body: reason (PublicArchivalReasonEnum, required) - Why the organization is being archived. allowed values: BILLING_PRICING, ONBOARDING_FRICTION, PRODUCT_FIT, DATA_ACCURACY_TRUST, TECHNICAL_SETUP_ISSUES, RESPONSIVENESS_SUPPORT, INTERNAL_CHANGES, TIMING_READINESS, MOVED_TO_COMPETITOR, NO_LONGER_NEEDED, OTHER notes (string) - Free-text detail. Required when reason is OTHER. Response fields: id (string, required) - Opaque unique identifier of the organization. organizationId (string, required) - Owning organization id. For an organization this equals `id`, included so every resource on the surface carries `organizationId` uniformly. name (string, required) - Display name of the organization. Empty string if unset. status (PublicOrganizationStatusEnum, required) - Lifecycle status of the organization. allowed values: ACTIVE, ARCHIVED city (string, required) - Company city. Empty string if unset. state (string, required) - Company state. Empty string if unset. details (OrganizationDetails) - Directory-detail fields (entity type, masked EIN, industry, primary contact, registered-state count, portfolio join date). Present only when the request passes `include=details`; omitted otherwise. entityType (PublicEntityTypeEnum, required) - Legal entity type, or null if not captured. allowed values: C_CORPORATION, COOPERATIVE_CO_OP, CORPORATION, GENERAL_PARTNERSHIP, HYBRID_LLC, JOINT_VENTURE, LLC, LLC_TAXED_AS_C_CORPORATION, LLC_TAXED_AS_S_CORPORATION, LIMITED_LIABILITY_LIMITED_PARTNERSHIP, LIMITED_LIABILITY_PARTNERSHIP, LIMITED_PARTNERSHIP (and 6 more, see the reference page) einMasked (string, required) - Employer Identification Number with all but the last four digits masked, or null if no EIN is on file. industry (string, required) - NAICS industry code, or null if not captured. [truncated, see the reference page] --- # List physical presences GET /physical-nexus Source: https://docs.trykintsugi.com/reference/2026-07-21/list-physical-presences GET /physical-nexus List physical presences Returns a keyset page of the physical presences recorded for organizations your credential owns. Defaults to country, then state, then category order; sort with `orderBy`/`order`, and omit `orderBy` to page in that default order. Send `Organization-Id`, `Connection-Id`, or `Entity-Id` to narrow to one organization. A cursor is valid only for the sort, filters and organization scope that issued it. Category: Physical nexus Query parameters: orderBy (PublicPhysicalNexusSortEnum) - Field to sort by. Omit to page in the default country, then state, then category order. allowed values: countryCode, stateCode, category, startDate, endDate, createdAt order (PublicPhysicalNexusSortOrder) - Sort direction. Applies only when `orderBy` is set. allowed values: asc, desc countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes. Matches any listed value. stateCode (string) - Comma-separated state or province codes. Matches any listed value. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (PhysicalNexus[], required) - Physical nexus rows on this page. id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. organizationHasTransactions (boolean, required) - Whether the owning organization has any transactions. Editing a closed presence would move a date that nexus was already calculated against, so clients disable editing when this is `true` and `endDate` is set. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. category (PublicPhysicalNexusCategoryEnum, required) - Kind of physical presence this record describes. Which categories a jurisdiction accepts varies; get the catalog from `GET /physical-nexus/categories`. Ignore unrecognized values. [truncated, see the reference page] --- # Record a physical presence POST /physical-nexus Source: https://docs.trykintsugi.com/reference/2026-07-21/record-a-physical-presence POST /physical-nexus Record a physical presence Record a physical presence in one jurisdiction. Recording a presence can establish nexus there, so the jurisdiction's exposure is recalculated. One record exists per organization, jurisdiction and category: a second create for the same three returns 200. A category the jurisdiction does not accept returns 400; get the accepted set from `GET /physical-nexus/categories`. Category: Physical nexus Request body: countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. category (PublicPhysicalNexusCategoryEnum, required) - Kind of physical presence to record. A category the jurisdiction does not accept returns 400; get the accepted set from `GET /physical-nexus/categories`. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) startDate (string, required) - Date the physical presence began, as YYYY-MM-DD. endDate (string) - Date the physical presence ended, as YYYY-MM-DD. Omit it or send `null` while the presence is open-ended. Must not precede `startDate`. externalId (string) - Your identifier for this record in an external system. street1 (string) - Street address of the location. street2 (string) - Suite, unit, or other address detail. city (string) - City of the location. postalCode (string) - ZIP or postal code of the location. Response fields: id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. [truncated, see the reference page] --- # List the physical presence category catalog GET /physical-nexus/categories Source: https://docs.trykintsugi.com/reference/2026-07-21/list-the-physical-presence-category-catalog GET /physical-nexus/categories List the physical presence category catalog List the physical presence categories a jurisdiction accepts. Each `name` is a value `category` accepts on a create or an update, and `isCategoryAssigned` reports whether the organization already records that category in this jurisdiction. Because that flag is organization data, this route needs exactly one organization: send `Organization-Id`, `Connection-Id`, or `Entity-Id` if your credential reaches more than one. Category: Physical nexus Query parameters: countryCode (string) - ISO 3166-1 alpha-2 country of the jurisdiction. Defaults to `US`. stateCode (string) - State or province code within `countryCode`. Omit it for the country-level catalog, in which case no category reads as assigned. Response fields: name (PublicPhysicalNexusCategoryEnum, required) - The category value. Send it as `category` on a create or an update. Ignore unrecognized values. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) title (string, required) - Display label for this category. Empty if none is defined. description (string, required) - What this category covers. Empty if no description is defined. example (string, required) - Worked example of a presence in this category. Empty if none is defined. isCategoryAssigned (boolean, required) - Whether the resolved organization already records this category in the requested jurisdiction. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a physical presence GET /physical-nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-physical-presence GET /physical-nexus/{physical_nexus_id} Get a physical presence Returns one physical presence. Searches every organization your credential owns, so no selector is needed for a known id. Returns 404 if the record does not exist or is not visible to your credential. Category: Physical nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus. Response fields: id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. organizationHasTransactions (boolean, required) - Whether the owning organization has any transactions. Editing a closed presence would move a date that nexus was already calculated against, so clients disable editing when this is `true` and `endDate` is set. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the jurisdiction, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code within `countryCode`. `FD` for a federal jurisdiction. category (PublicPhysicalNexusCategoryEnum, required) - Kind of physical presence this record describes. Which categories a jurisdiction accepts varies; get the catalog from `GET /physical-nexus/categories`. Ignore unrecognized values. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) source (PublicPhysicalNexusSourceEnum, required) - What created this record. `USER` for one you recorded through the API or the app; `DEEL` for one synced from the organization's Deel integration. Ignore unrecognized values. allowed values: USER, DEEL startDate (string, required) - Date the physical presence began, as YYYY-MM-DD. endDate (string) - Date the physical presence ended, as YYYY-MM-DD. `null` while it is open-ended. [truncated, see the reference page] --- # Update a physical presence PATCH /physical-nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-physical-presence PATCH /physical-nexus/{physical_nexus_id} Update a physical presence Update a physical presence. A field you omit, or send as null, is left unchanged. Changing the category or the dates can change whether the jurisdiction has nexus, so its exposure is recalculated. The jurisdiction itself is not editable: delete the record and create it under the country and state you want. A category the jurisdiction does not accept returns 400, and a category already recorded for this jurisdiction returns 409. Category: Physical nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus. Request body: category (PublicPhysicalNexusCategoryEnum) - New kind of physical presence. A category the jurisdiction does not accept returns 400. Omit it or send `null` to leave it unchanged. allowed values: PHYSICAL_BUSINESS_LOCATION, TELECOMMUTING_OR_REMOTE_EMPLOYEE, WARRANTY_AND_REPAIR_SERVICES, CATALOGUE_DISTRIBUTION_OR_ADVERTISING_MATERIAL, DELIVERY_BY_COMMON_CARRIER, DELIVERY_BY_OWN_VEHICLES, IN_STATE_SALES_PERSON, INDEPENDENT_CONTRACTOR_OR_THIRD_PARTY_SALES_PERSON, WAREHOUSE_AND_INVENTORY_PRESENCE, EMPLOYEES_AGENTS_CONTRACTORS, OWN_LEASE_A_PROPERTY, INVENTORY (and 14 more, see the reference page) startDate (string) - New date the physical presence began. Omit it or send `null` to leave it unchanged. endDate (string) - New date the physical presence ended. Omit it or send `null` to leave it unchanged; this endpoint cannot reopen a closed presence. Must not precede the effective `startDate`. street1 (string) - New street address. Omit it or send `null` to leave it unchanged, or an empty string to clear it. street2 (string) - New suite, unit, or other address detail. Omit it or send `null` to leave it unchanged, or an empty string to clear it. city (string) - New city. Omit it or send `null` to leave it unchanged, or an empty string to clear it. postalCode (string) - New ZIP or postal code. Omit it or send `null` to leave it unchanged, or an empty string to clear it. Response fields: id (string, required) - Opaque unique identifier for this physical nexus. organizationId (string, required) - Organization this physical nexus belongs to. Always present so a portfolio list that spans organizations stays unambiguous. organizationName (string) - Display name of the owning organization. `null` if the name could not be loaded. [truncated, see the reference page] --- # Delete a physical presence DELETE /physical-nexus/{physical_nexus_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/delete-a-physical-presence DELETE /physical-nexus/{physical_nexus_id} Delete a physical presence Delete a physical presence. Removing it can end nexus in that jurisdiction, so the jurisdiction's exposure is recalculated. Returns 404 if the record does not exist or belongs to an organization your credential cannot access. Category: Physical nexus Path parameters: physical_nexus_id (string, required) - The unique identifier of the physical nexus. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # List products GET /products Source: https://docs.trykintsugi.com/reference/2026-07-21/list-products GET /products List products List products, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Filter with `status`, `source` (comma-separated), `search`, `productCategory` and `productSubcategory`, and sort with `orderBy`/`order`; omit `orderBy` to page in the default id order. Pass `limit` and the opaque `cursor` from a prior response to page. A cursor is only valid for the sort, filters AND organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Products Query parameters: orderBy (PublicProductSortEnum) - Field to sort by. Omit to page in the default id order (fastest); the other keys sort the whole matching set. allowed values: name, status, createdAt, externalId, source order (PublicProductSortOrder) - Sort direction. Applies only when `orderBy` is set. allowed values: asc, desc status (string) - Comma-separated approval statuses; matches any of them. source (string) - Comma-separated source systems; matches any of them. search (string) - Search over product id, externalId, name and description. id and externalId must match exactly; name and description match a case-insensitive substring. productCategory (PublicProductCategoryEnum) - Tax category to filter by. Matches every product in the category regardless of subcategory; combine with productSubcategory to narrow. allowed values: Physical, Digital, Misc, Services productSubcategory (string) - Tax subcategory display label to filter by (e.g. 'General Clothing'). An unrecognized label matches no products. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Product[], required) - The results on this page. Empty when there are none. id (string, required) - Kintsugi's unique identifier for the product. organizationId (string, required) - Organization the product belongs to. Send it as `Organization-Id` to scope a request to this product. organizationName (string) - Display name of the organization the product belongs to. `null` when the organization has no name set. externalId (string, required) - Your stable identifier for the product, as supplied on create. [truncated, see the reference page] --- # Create a product POST /products Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-product POST /products Create a product Create a product in the resolved organization. Idempotent on `externalId` and `source`: sending the same values again returns the existing product unchanged and responds `200` instead of creating a duplicate. If the match is a product you previously deleted, it is restored (not duplicated) so its tax history stays attached to it; a restored product re-enters classification and its `status` returns to `PENDING`, so it is not used in tax calculation until it is approved again. The product is not otherwise updated by this call; use `PATCH /products/{productId}` to update. `source` accepts only the curated public values. `status` does not accept ARCHIVED; archive an existing product with `DELETE /products/{productId}`. Category: Products Request body: externalId (string, required) - Your stable identifier for the product. Creating another product with the same externalId and source returns the existing product (200) instead of a duplicate; use PATCH to update it. The same externalId can still appear on products synced from your connections. name (string, required) - Human-readable product name. description (string) - Optional product description. status (PublicProductCreateStatusEnum) - Approval status of the product's tax classification. ARCHIVED is not accepted here: archive an existing product with DELETE /products/{id}. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING productCategory (PublicProductCategoryEnum, required) - Top-level tax category for the product. allowed values: Physical, Digital, Misc, Services productSubcategory (string, required) - Tax subcategory display label within the category (e.g. 'General Clothing', 'B2B SaaS'). Together with productCategory it resolves to a product tax code; an unrecognized pair returns 400. taxExempt (boolean, required) - Whether the product is treated as tax-exempt by tax calculation. This is the effective exemption flag applied to transactions. source (string) - Origin system of the product (e.g. API, SHOPIFY). Defaults to OTHER. Must be a supported public source; unsupported values are rejected. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) [truncated, see the reference page] --- # Approve partially-approved products in bulk POST /products/bulk-approve Source: https://docs.trykintsugi.com/reference/2026-07-21/approve-partially-approved-products-in-bulk POST /products/bulk-approve Approve partially-approved products in bulk Approve partially-approved products in one organization, either by naming `productIds` (at most 100) or by `filters`. Provide exactly one of the two: sending both, or neither, returns 400. The approval is atomic: either every matched product is approved or none is. `approvedCount` and `skippedCount` report what actually changed, not how many you asked for. An id that is not partially-approved, does not exist, or belongs to an organization your credential cannot access is counted in `skippedCount`, never approved. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productIds (string[]) - Explicit product ids to approve (at most 100). Mutually exclusive with filters; provide exactly one of the two. An id that is not partially-approved, not found, or in an organization you cannot access is counted in skippedCount, never approved. filters (BulkApproveFilters) - Attribute filters selecting which partially-approved products to approve. Mutually exclusive with productIds; provide exactly one of the two. productCategory (PublicProductCategoryEnum) - Approve only products in this tax category. Omit to match any category. Combine with productSubcategory and/or source to narrow further. allowed values: Physical, Digital, Misc, Services productSubcategory (string) - Approve only products whose tax subcategory display label matches (e.g. 'General Clothing'). Omit to match any subcategory. source (string) - Approve only products from this origin system (e.g. API, SHOPIFY). Must be a supported public source; unsupported values are rejected. Omit to match any source. Response fields: approvedCount (integer, required) - Number of products moved to APPROVED by this request. skippedCount (integer, required) - Number of requested products left unchanged because they were not partially-approved, not found, or outside your access. Always 0 for a filter-based request. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Approve partially-approved products by category POST /products/bulk-approve-by-category Source: https://docs.trykintsugi.com/reference/2026-07-21/approve-partially-approved-products-by-category POST /products/bulk-approve-by-category Approve partially-approved products by category Approve EVERY partially-approved product in one organization that falls under the given `categories`, with one bulk update per category. Unlike `bulk-approve` (capped at 100 ids), this is how you approve a whole category without paging ids. Each `productCategory`/`productSubcategory` pair must resolve to a product tax code or the request returns 400. `approvedCount` is the total actually moved to APPROVED across all categories. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: categories (ProductCategorySelector[], required) - Category/subcategory pairs to approve. Every partially-approved product in each pair is moved to APPROVED. Provide at least one. productCategory (PublicProductCategoryEnum, required) - Top-level tax category to approve products in. allowed values: Physical, Digital, Misc, Services productSubcategory (string, required) - Tax subcategory display label within the category (e.g. 'General Clothing'). Together with productCategory it must resolve to a product tax code; an unrecognized pair returns 400. Response fields: approvedCount (integer, required) - Total number of products moved to APPROVED across all requested categories. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get the resolved organization's in-progress bulk-classification import GET /products/bulk-classifications/active-review Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-resolved-organization-s-in-progress-bulk-classification-import GET /products/bulk-classifications/active-review Get the resolved organization's in-progress bulk-classification import Return the resolved organization's bulk-classification import that is still awaiting a decision or applying, or `null` when there is none. Lets a client restore an in-progress review after losing the import id (a page reload). Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED productsToUpdate (integer, required) - Products this import will update once confirmed. productsToSkip (integer, required) - Rows that failed validation and will not be applied. productsIgnored (integer, required) - Rows that matched no change (already at the target category). skipReasons (ProductBulkClassificationSkipReasonCount[], required) - Skipped-row counts, broken down by reason. reason (PublicProductBulkSkipReasonEnum, required) - Why a row in a bulk-classification CSV was skipped rather than applied. allowed values: INVALID_PRODUCT, INVALID_CATEGORY, INVALID_SUBCATEGORY, INVALID_CATEGORY_AND_SUBCATEGORY, INVALID_APPROVAL_STATUS, CONFLICT count (integer, required) - Number of rows skipped for this reason. hasRejectedArtifact (boolean, required) - Whether a downloadable file of rejected rows exists. hasPreviewArtifact (boolean, required) - Whether a before/after preview is available. confirmedBy (string) - Id of the user who confirmed this import, or null if unconfirmed. confirmedAt (string) - When this import was confirmed, as an RFC-3339 UTC timestamp; null if unconfirmed. progressImported (integer) - Rows successfully applied so far; null before the apply is confirmed. progressRows (integer) - Total rows claimed for apply; null before the apply is confirmed. progressFailed (integer) - Rows that failed to apply so far; null before the apply is confirmed. [truncated, see the reference page] --- # Cancel a bulk-classification import POST /products/bulk-classifications/{import_id}/cancel Source: https://docs.trykintsugi.com/reference/2026-07-21/cancel-a-bulk-classification-import POST /products/bulk-classifications/{import_id}/cancel Cancel a bulk-classification import Cancel a bulk-classification import before it is confirmed. Returns 404 if the import does not exist or belongs to an organization your credential cannot access, and 409 if it cannot be cancelled in its current state. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED alreadyCancelled (boolean) - True when this import was already cancelled. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Confirm a bulk-classification import POST /products/bulk-classifications/{import_id}/confirm Source: https://docs.trykintsugi.com/reference/2026-07-21/confirm-a-bulk-classification-import POST /products/bulk-classifications/{import_id}/confirm Confirm a bulk-classification import Confirm a review-ready bulk-classification import and queue it to apply. `idempotencyKey` makes a retried confirm safe: resending the same key returns the same result rather than confirming twice. Returns 409 if the import is not review-ready, has no valid rows, or a different `idempotencyKey` was already recorded for it. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Request body: idempotencyKey (string, required) - A caller-chosen key. Resending the same key for this import returns the same confirmation instead of confirming twice. Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED confirmedBy (string) - Id of the user who confirmed this import, or null if unconfirmed. alreadyConfirmed (boolean) - True when this confirm resent an idempotency key that was already recorded, rather than confirming for the first time. Response statuses: 202, 400, 401, 403, 404, 409, 422, 503 --- # Get a bulk-classification import's before/after preview GET /products/bulk-classifications/{import_id}/preview Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-bulk-classification-import-s-before-after-preview GET /products/bulk-classifications/{import_id}/preview Get a bulk-classification import's before/after preview Return one page of the before/after tax-category preview for a bulk-classification import. Returns 404 if the import does not exist or belongs to an organization your credential cannot access, and 503 if the preview content is temporarily unavailable. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Query parameters: page (integer) size (integer) Response fields: importId (string, required) - The unique identifier of this import. page (integer, required) - The page number returned, starting at 1. size (integer, required) - Rows requested per page. total (integer, required) - Total previewable rows across all pages. items (ProductBulkClassificationPreviewRow[], required) - This page's rows. productId (string, required) - The unique identifier of the product. productName (string) - The product's name; null if not resolvable. externalId (string) - Your identifier for the product; null if not resolvable. beforeCategory (string) - Current tax category; null if the product is new. afterCategory (string) - Tax category this row will change the product to. beforeSubcategory (string) - Current tax subcategory; null if the product is new. afterSubcategory (string) - Tax subcategory this row will change the product to. beforeStatus (string) - Current classification status; null if the product is new. afterStatus (string) - Classification status this row will change the product to. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Get a bulk-classification import's rejected-rows file GET /products/bulk-classifications/{import_id}/rejected-file Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-bulk-classification-import-s-rejected-rows-file GET /products/bulk-classifications/{import_id}/rejected-file Get a bulk-classification import's rejected-rows file Return download instructions for the rows rejected from a bulk-classification import. Returns 404 if the import does not exist, belongs to an organization your credential cannot access, or has no rejected-rows file. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: downloadUrl (string, required) - Presigned URL to download the rejected rows; empty when the content is returned inline via `inlineContentBase64` instead. expiresInSeconds (integer, required) - Seconds until `downloadUrl` expires. inlineContentBase64 (string) - Base64-encoded rejected-rows content, when small enough to return inline instead of via `downloadUrl`. downloadName (string) - Suggested filename for the downloaded content. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Get a bulk-classification import's review state GET /products/bulk-classifications/{import_id}/review Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-bulk-classification-import-s-review-state GET /products/bulk-classifications/{import_id}/review Get a bulk-classification import's review state Return the validation summary and, once confirmed, the apply progress for a bulk-classification import. Returns 404 if the import does not exist or belongs to an organization your credential cannot access. Category: Products Path parameters: import_id (string, required) - The unique identifier of the import. Response fields: importId (string, required) - The unique identifier of this import. status (PublicProductImportStatusEnum, required) - Lifecycle status of a bulk-classification import. Every pre-validation internal status (queued, submitted, virus scan, validating) reports as VALIDATING. A virus-scan failure reports as VALIDATION_FAILURE. An import archived before completion reports as CANCELLED. allowed values: VALIDATING, VALIDATION_SUCCESS, VALIDATION_FAILURE, CONFIRM_PENDING, IMPORT_STARTED, IMPORTING, SUCCESS, FAILURE, CANCELLED productsToUpdate (integer, required) - Products this import will update once confirmed. productsToSkip (integer, required) - Rows that failed validation and will not be applied. productsIgnored (integer, required) - Rows that matched no change (already at the target category). skipReasons (ProductBulkClassificationSkipReasonCount[], required) - Skipped-row counts, broken down by reason. reason (PublicProductBulkSkipReasonEnum, required) - Why a row in a bulk-classification CSV was skipped rather than applied. allowed values: INVALID_PRODUCT, INVALID_CATEGORY, INVALID_SUBCATEGORY, INVALID_CATEGORY_AND_SUBCATEGORY, INVALID_APPROVAL_STATUS, CONFLICT count (integer, required) - Number of rows skipped for this reason. hasRejectedArtifact (boolean, required) - Whether a downloadable file of rejected rows exists. hasPreviewArtifact (boolean, required) - Whether a before/after preview is available. confirmedBy (string) - Id of the user who confirmed this import, or null if unconfirmed. confirmedAt (string) - When this import was confirmed, as an RFC-3339 UTC timestamp; null if unconfirmed. progressImported (integer) - Rows successfully applied so far; null before the apply is confirmed. progressRows (integer) - Total rows claimed for apply; null before the apply is confirmed. progressFailed (integer) - Rows that failed to apply so far; null before the apply is confirmed. [truncated, see the reference page] --- # Queue products for reclassification POST /products/bulk-classify Source: https://docs.trykintsugi.com/reference/2026-07-21/queue-products-for-reclassification POST /products/bulk-classify Queue products for reclassification Queue this credential's products for AI tax reclassification. By default it covers every organization you own; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. For each organization, products whose classification failed or is only partially approved are flagged and a classification batch is enqueued to run asynchronously. Returns 202 with `orgsQueued`, the number of organizations queued — the work itself completes in the background. Category: Products Response fields: orgsQueued (integer, required) - Number of organizations whose products were queued for reclassification. With no selector this is every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Response statuses: 202, 400, 401, 403, 404, 409, 422 --- # List the product category catalog GET /products/categories Source: https://docs.trykintsugi.com/reference/2026-07-21/list-the-product-category-catalog GET /products/categories List the product category catalog List every tax category and the subcategory labels valid under it. Use it to build category/subcategory pickers: the `category` and each `label` are the exact values `productCategory` and `productSubcategory` accept on create, update and recategorize. The catalog is the same for every caller. Category: Products Response fields: category (PublicProductCategoryEnum, required) - Top-level tax category. Send it as `productCategory` on writes. allowed values: Physical, Digital, Misc, Services subcategories (ProductSubcategory[], required) - Subcategories valid under this category. Never empty. label (string, required) - Subcategory display label. Send it as `productSubcategory`, paired with the category, on create/patch to resolve a product tax code. description (string, required) - What this subcategory covers for sales-tax purposes. example (string, required) - Example products or services in this subcategory. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Categorize and approve products POST /products/categorize-approve Source: https://docs.trykintsugi.com/reference/2026-07-21/categorize-and-approve-products POST /products/categorize-approve Categorize and approve products Assign a `productCategory`/`productSubcategory` to the named products AND set them APPROVED, in one call. Unlike `bulk-approve` (which only moves partially-approved products), this classifies and signs off any products you name, at most 100. Every id must belong to the resolved organization; an id that does not exist or is in an organization you cannot access returns 404 and nothing is changed. The category/subcategory pair must resolve to a product tax code or the request returns 400. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productIds (string[], required) - Products to categorize and approve (at most 100). Every id must belong to the resolved organization; an unknown id returns 404 and nothing is changed. productCategory (PublicProductCategoryEnum, required) - Tax category to assign to every product. allowed values: Physical, Digital, Misc, Services productSubcategory (string, required) - Tax subcategory display label to assign (e.g. 'General Clothing'). Together with productCategory it must resolve to a product tax code; an unrecognized pair returns 400. Response fields: updatedCount (integer, required) - Number of products that were assigned the category/subcategory and moved to APPROVED. Equals the number of distinct ids you sent. Response statuses: 200, 400, 401, 403, 404, 422 --- # Summarize product classification progress GET /products/classification-progress Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-product-classification-progress GET /products/classification-progress Summarize product classification progress Count products by classification outcome across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Category: Products Response fields: total (integer, required) - Product count across the resolved organizations. classified (integer, required) - Products with APPROVED classification status. pending (integer, required) - Products with PENDING or PARTIALLY_APPROVED classification status. failed (integer, required) - Products where classification failed. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Check whether bulk classification can run GET /products/classification-status Source: https://docs.trykintsugi.com/reference/2026-07-21/check-whether-bulk-classification-can-run GET /products/classification-status Check whether bulk classification can run Report whether `POST /products/bulk-classify` is worth running, across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. `canClassify` is true only when `totalProducts` meets `minProducts` and at least one product needs classification work: pending, or a status `POST /products/bulk-classify` would reset and re-run. Category: Products Query parameters: minProducts (integer) - Minimum product count required for `canClassify` to be true. Response fields: canClassify (boolean, required) - Whether POST /products/bulk-classify is worth running: enough products exist and at least one needs classification work, meaning it is pending or is a status bulk-classify would reset and re-run (partially approved or previously failed classification). totalProducts (integer, required) - Product count across the resolved organizations. hasPendingProducts (boolean, required) - Whether any resolved organization has a product in PENDING status. minProducts (integer, required) - The product count `totalProducts` must meet for `canClassify` to be true. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List product configurations GET /products/configs Source: https://docs.trykintsugi.com/reference/2026-07-21/list-product-configurations GET /products/configs List product configurations List product tax-category overrides, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Unsorted and unfiltered: pages walk in id order. Category: Products Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (ProductConfig[], required) - The results on this page. Empty when there are none. id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. isDefault (boolean, required) - Whether this is the organization's default configuration, applied when no other configuration matches a product. At most one configuration per organization may be the default. nextCursor (string) - Opaque cursor for the next page. `null` when this is the last page. Send it back as `cursor`; do not parse it. previousCursor (string) - Opaque cursor for the previous page. `null` when this is the first page. Send it back as `cursor`; do not parse it. hasMore (boolean) - Whether a page exists after this one. hasPrevious (boolean) - Whether a page exists before this one. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Create a product configuration POST /products/configs Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-product-configuration POST /products/configs Create a product configuration Create a product tax-category override for the resolved organization. `primaryProductCategory` and `primaryProductSubcategory` must resolve to a supported product tax code, or the request returns 400. At most one configuration per organization may set `isDefault`; creating a new default clears the previous one. Returns 409 if a configuration or blocklist entry already exists for the resolved tax code. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category. Must resolve to a supported tax code together with `primaryProductSubcategory`. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label, e.g. from `GET /products/categories`. aiEnabled (boolean) - Let the classifier choose among tax codes under this category rather than always applying the one resolved code. productDescription (string) - Free-text note about this configuration. isDefault (boolean) - Make this the organization's default configuration. Creating a new default clears the previous one. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. [truncated, see the reference page] --- # List blocklisted product codes GET /products/configs/blocklist Source: https://docs.trykintsugi.com/reference/2026-07-21/list-blocklisted-product-codes GET /products/configs/blocklist List blocklisted product codes List product tax codes excluded from onboarding suggestions, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Category: Products Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (ProductConfigBlocklistEntry[], required) - The results on this page. Empty when there are none. id (string, required) - The unique identifier of this blocklist entry. organizationId (string, required) - The organization this blocklist entry belongs to. productCodeName (string, required) - The blocklisted product tax code. nextCursor (string) - Opaque cursor for the next page. `null` when this is the last page. Send it back as `cursor`; do not parse it. previousCursor (string) - Opaque cursor for the previous page. `null` when this is the first page. Send it back as `cursor`; do not parse it. hasMore (boolean) - Whether a page exists after this one. hasPrevious (boolean) - Whether a page exists before this one. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Add a product code to the blocklist POST /products/configs/blocklist Source: https://docs.trykintsugi.com/reference/2026-07-21/add-a-product-code-to-the-blocklist POST /products/configs/blocklist Add a product code to the blocklist Exclude a product tax code from onboarding suggestions for the resolved organization. Idempotent: blocklisting an already-blocklisted code returns 200 with the existing entry rather than an error or a second 201. Returns 400 if `productCodeName` is not a recognized product tax code, and 409 if it already has a configuration (remove the configuration first). Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productCodeName (string, required) - The product tax code to exclude from onboarding suggestions. Response fields: id (string, required) - The unique identifier of this blocklist entry. organizationId (string, required) - The organization this blocklist entry belongs to. productCodeName (string, required) - The blocklisted product tax code. Response statuses: 200, 201, 400, 401, 403, 404, 409, 422 --- # Remove a product code from the blocklist DELETE /products/configs/blocklist/{product_code_name} Source: https://docs.trykintsugi.com/reference/2026-07-21/remove-a-product-code-from-the-blocklist DELETE /products/configs/blocklist/{product_code_name} Remove a product code from the blocklist Remove a product tax code from the blocklist. Returns 404 if it is not on the blocklist for the resolved organization. Category: Products Path parameters: product_code_name (string, required) - The product tax code to remove from the blocklist. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Create product configurations in bulk POST /products/configs/bulk Source: https://docs.trykintsugi.com/reference/2026-07-21/create-product-configurations-in-bulk POST /products/configs/bulk Create product configurations in bulk Create several product tax-category overrides for the resolved organization in one call. All entries succeed together, or none do: if any entry's category/subcategory does not resolve to a supported product tax code, or two entries (or an entry and an existing configuration) resolve to the same one, the whole request returns 400 or 409 and nothing is created. At most one entry across the whole request may set `isDefault`. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: productConfigs (ProductConfigCreate[], required) - The configurations to create. All succeed together, or none do. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category. Must resolve to a supported tax code together with `primaryProductSubcategory`. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label, e.g. from `GET /products/categories`. aiEnabled (boolean) - Let the classifier choose among tax codes under this category rather than always applying the one resolved code. productDescription (string) - Free-text note about this configuration. isDefault (boolean) - Make this the organization's default configuration. Creating a new default clears the previous one. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. [truncated, see the reference page] --- # Get a product configuration by id GET /products/configs/{config_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-product-configuration-by-id GET /products/configs/{config_id} Get a product configuration by id Fetch a single product configuration by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Products Path parameters: config_id (string, required) - The unique identifier of the product configuration. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. isDefault (boolean, required) - Whether this is the organization's default configuration, applied when no other configuration matches a product. At most one configuration per organization may be the default. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Update a product configuration PATCH /products/configs/{config_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-product-configuration PATCH /products/configs/{config_id} Update a product configuration Update a product configuration's editable fields. This is a partial update: only the fields you send change; any field you omit is left as-is. Send `primaryProductCategory` and `primaryProductSubcategory` together to change the category; sending only one returns 400. Returns 404 if the configuration does not exist or belongs to an organization your credential cannot access, and 409 if the change would duplicate another configuration's tax code. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Path parameters: config_id (string, required) - The unique identifier of the product configuration. Request body: primaryProductCategory (PublicProductCategoryEnum) - New top-level tax category. Send together with `primaryProductSubcategory`. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string) - New tax subcategory display label. aiEnabled (boolean) - Let the classifier choose among tax codes under this category. productDescription (string) - Free-text note about this configuration. isDefault (boolean) - Make this the organization's default configuration. Creating a new default clears the previous one. Response fields: id (string, required) - The unique identifier of this configuration. organizationId (string, required) - The organization this configuration belongs to. primaryProductCategory (PublicProductCategoryEnum, required) - Top-level tax category derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published category. allowed values: Physical, Digital, Misc, Services primaryProductSubcategory (string, required) - Tax subcategory display label derived from `primaryProductCodeName`. `null` only if the stored code no longer resolves to a published subcategory. primaryProductCodeName (string, required) - The resolved product tax code this configuration applies. `null` only for a config predating this field's backfill, which has not yet been reclassified. aiEnabled (boolean, required) - Whether the classifier may choose among tax codes under this configuration's category rather than always applying one fixed code. productDescription (string, required) - Free-text note about this configuration. Empty when not set. [truncated, see the reference page] --- # Delete a product configuration DELETE /products/configs/{config_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/delete-a-product-configuration DELETE /products/configs/{config_id} Delete a product configuration Delete a product configuration by id. Returns 404 if it does not exist or belongs to an organization your credential cannot access. Category: Products Path parameters: config_id (string, required) - The unique identifier of the product configuration. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Break down products by category GET /products/overview Source: https://docs.trykintsugi.com/reference/2026-07-21/break-down-products-by-category GET /products/overview Break down products by category Count products by organization, tax category and subcategory across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Each row is one organization's count for a category/subcategory. Archived products are never counted. Rows are ordered by organization, then category, then subcategory. Category: Products Response fields: organizationId (string, required) - Organization this count is for. Send it as `Organization-Id` to scope a follow-up request to this organization's products. productCategory (string, required) - Derived display category for the product tax code. productSubcategory (string, required) - Derived display subcategory for the product tax code. count (integer, required) - Number of products in scope with this category/subcategory. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Recategorize products in bulk POST /products/recategorize Source: https://docs.trykintsugi.com/reference/2026-07-21/recategorize-products-in-bulk POST /products/recategorize Recategorize products in bulk Move products in one organization from one category/subcategory to another. Every product matching `existingCategory`/`existingSubcategory` is reassigned to `newCategory`/`newSubcategory`, which must resolve to a supported tax code or the request returns 400. Pass `statusList` to move only products currently in those approval statuses. The reassignment runs asynchronously; the response is a 202 with `orgsQueued`. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: existingCategory (PublicProductCategoryEnum, required) - Current top-level tax category of the products to move. allowed values: Physical, Digital, Misc, Services existingSubcategory (string, required) - Current tax subcategory display label of the products to move (e.g. 'General Clothing'). With existingCategory it selects which products recategorize. newCategory (PublicProductCategoryEnum, required) - New top-level tax category to assign to the matched products. allowed values: Physical, Digital, Misc, Services newSubcategory (string, required) - New tax subcategory display label to assign (e.g. 'Catering'). With newCategory it must resolve to a supported product tax code; an unrecognized pair returns 400. statusList (PublicProductStatusEnum[]) - Optional approval-status filter: only move products currently in one of these statuses. Omit to move every product matching the existing category/subcategory pair regardless of status. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED Response fields: orgsQueued (integer, required) - Number of organizations queued for recategorization. Always 1: a recategorize targets the single organization resolved from your credential and any `Organization-Id` selector. Response statuses: 202, 400, 401, 403, 404, 422 --- # Export products POST /products/reports/export Source: https://docs.trykintsugi.com/reference/2026-07-21/export-products POST /products/reports/export Export products Queue a products export for one organization. The report is generated asynchronously and a download link is emailed, so the response is a 202 rather than the file itself. An API-key credential must provide `email`; a first-party bearer session may omit it to send the report to its own account email. Returns 400 if the organization has disabled email delivery. Send the target organization as `Organization-Id` when your credential owns more than one. Category: Products Request body: email (string) - Address the generated report download link is emailed to. Required for an API-key credential (it has no session user). For a first-party bearer session it is optional: omit it to send the report to your own account email. Response fields: organizationId (string, required) - Organization the export was queued for. email (string, required) - Address the report download link will be emailed to. Response statuses: 202, 400, 401, 403, 404, 422 --- # Summarize products by status GET /products/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-products-by-status GET /products/summary Summarize products by status Count products by approval status across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Archived products are never counted. `total` is the sum of `statusCounts`. Category: Products Response fields: total (integer, required) - Total products in scope, the sum of `statusCounts`. Excludes archived products. statusCounts (ProductStatusCount[], required) - One entry per status present in scope. A status with no products is omitted rather than reported as zero. status (PublicProductStatusEnum, required) - The approval status this count is for. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED count (integer, required) - Number of products in scope with this status. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a product by id GET /products/{product_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-product-by-id GET /products/{product_id} Get a product by id Fetch a single product by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Products Path parameters: product_id (string, required) - The unique identifier of the product. Response fields: id (string, required) - Kintsugi's unique identifier for the product. organizationId (string, required) - Organization the product belongs to. Send it as `Organization-Id` to scope a request to this product. organizationName (string) - Display name of the organization the product belongs to. `null` when the organization has no name set. externalId (string, required) - Your stable identifier for the product, as supplied on create. sku (string[]) - SKUs associated with the product. An empty list when it has none. code (string, required) - Derived product tax code display name. name (string, required) - Human-readable product name. description (string) - Product description; an empty string when the product has none. status (PublicProductStatusEnum, required) - Approval status of the product's tax classification. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING, ARCHIVED productCategory (string, required) - Derived display category for the product's tax code. productSubcategory (string, required) - Derived display subcategory for the product's tax code. taxExempt (boolean, required) - Effective tax-exemption flag applied by tax calculation. sourceTaxExempt (boolean) - Raw tax-exempt signal reported by the source system (audit). `null` when the source system did not report a signal, which is distinct from an explicit `false`. source (string, required) - Origin system of the product (e.g. API, SHOPIFY). Any origin outside the published values is reported as OTHER. allowed values: ACUMATICA, AIRWALLEX, AMAZON, API, APPLE_APP_STORE, BESTBUY, BIGCOMMERCE, BILL_COM, BUNNY, CAMPFIRE, CHARGEBEE, CHECKOUTCHAMP (and 58 more, see the reference page) connectionId (string) - Identifier of the connection that produced the product. `null` when the product was not produced by a connection (e.g. created manually). storeName (string) - Display name of the connection (store) that produced the product. `null` when the product has no connection, or the connection has no store name set. [truncated, see the reference page] --- # Update a product PATCH /products/{product_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-product PATCH /products/{product_id} Update a product Update a product's editable fields. This is a partial update: only the fields you send with a non-null value change; any field you omit or send as null is left as-is. `externalId` must stay unique per organization; reusing another product's value returns 409. `productCategory` and `productSubcategory` must resolve to a supported tax code or the request returns 400. `taxExempt` is honored when the category is unchanged; on a recategorize the exemption is derived from the new category and the sent value is ignored, and an exempt category is always tax-exempt. `source` is not editable. Returns 404 if the product does not exist, is archived, or belongs to an organization your credential cannot access. Category: Products Path parameters: product_id (string, required) - The unique identifier of the product. Request body: externalId (string) - New stable identifier for the product. Must stay unique per organization and source; a value already used by another product returns 409 Conflict. Omit it or send null to leave it unchanged; an empty string is rejected. name (string) - New human-readable product name. Omit it or send null to leave it unchanged; an empty string is rejected. description (string) - New product description. Send an empty string to clear it. Omit it or send null to leave it unchanged. productCategory (PublicProductCategoryEnum) - New top-level tax category. Together with productSubcategory it resolves to a product tax code; an unrecognized pair returns 400. Omit it or send null to leave it unchanged. allowed values: Physical, Digital, Misc, Services productSubcategory (string) - New tax subcategory display label within the category (e.g. 'General Clothing'). Together with productCategory it resolves to a product tax code; an unrecognized pair returns 400. Omit it or send null to leave it unchanged; an empty string is rejected. status (PublicProductCreateStatusEnum) - New approval status of the product's tax classification. ARCHIVED is not accepted here: archive a product with DELETE /products/{id}. Omit it or send null to leave it unchanged. allowed values: APPROVED, PARTIALLY_APPROVED, PENDING [truncated, see the reference page] --- # Archive a product DELETE /products/{product_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/archive-a-product DELETE /products/{product_id} Archive a product Archive a product. It is removed from this API: afterwards it is absent from `GET /products` and returns 404 from every read, exactly as a product that never existed does. The identity stays taken: creating a product again with the same `externalId` and `source` restores this product and returns it with `200`, and a transaction or sync that references the same `externalId` restores it too. Returns 404 if the product does not exist, is already archived, or belongs to an organization your credential cannot access. Category: Products Path parameters: product_id (string, required) - The unique identifier of the product. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Get the status of a public exemption request GET /public/exemption-requests/{token} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-status-of-a-public-exemption-request GET /public/exemption-requests/{token} Get the status of a public exemption request Read the status of the exemption request the link identifies: the jurisdictions the business requested a certificate for, their coverage status, and the certificates already uploaded. The link in the path is the only credential; no API key is needed. Returns 404 if the link is unknown and 410 if it is no longer available (completed, rejected, or expired). Category: Exemption Requests (Public) Path parameters: token (string, required) Response fields: jurisdictions (string[], required) - Jurisdictions the business requested a certificate for. jurisdictionStatuses (PublicJurisdictionStatus[], required) - Per-jurisdiction coverage status. state (string, required) - The jurisdiction (US state code). chipState (PublicJurisdictionChipState, required) - Derived badge state the page renders for this jurisdiction. allowed values: PENDING_NO_SUBMISSION, RECEIVED_REVIEW_PENDING, REJECTED, APPROVED uploadedCertificates (PublicUploadedCertificate[], required) - Certificates the purchaser has already uploaded. fileName (string, required) - Original file name the purchaser uploaded. submittedAt (string, required) - When the certificate was uploaded. statusPill (PublicCertificateStatusPill, required) - Display status of this certificate's review. Branch on this value. allowed values: SUBMITTED, REVIEW_IN_PROGRESS, APPROVED, REJECTED extractedJurisdictions (string[], required) - Jurisdictions detected on the certificate, if any. extractedCertificateType (string) - Certificate type detected on the document, or null if none was detected. requestStatusPill (PublicRequestStatusPill, required) - Request-level rollup status driving the confirmation headline. Branch on this value. allowed values: SUBMITTED, REVIEW_IN_PROGRESS, PARTIALLY_COMPLETED, APPROVED, REJECTED Response statuses: 200, 404, 410, 422 --- # Confirm uploaded certificates for an exemption request POST /public/exemption-requests/{token}/confirm-upload Source: https://docs.trykintsugi.com/reference/2026-07-21/confirm-uploaded-certificates-for-an-exemption-request POST /public/exemption-requests/{token}/confirm-upload Confirm uploaded certificates for an exemption request Confirm that files issued by a prior upload-urls call finished uploading to S3, so they can be processed. Send the `certificateImportId`s from that call. Returns 404 if an id is not part of this request, and 410 if the link is no longer available. Category: Exemption Requests (Public) Path parameters: token (string, required) Request body: certificateImportIds (string[], required) - The certificateImportIds whose uploads completed successfully. Response fields: confirmed (integer, required) - Number of uploads confirmed and queued for processing. Response statuses: 200, 400, 404, 410, 422 --- # Get the status of a public missing-certificate request GET /public/exemption-requests/{token}/missing-certificates Source: https://docs.trykintsugi.com/reference/2026-07-21/get-the-status-of-a-public-missing-certificate-request GET /public/exemption-requests/{token}/missing-certificates Get the status of a public missing-certificate request Read the status of the missing-certificate request the link identifies: the business and purchaser names, the jurisdictions a certificate is needed for, and their coverage status. The link in the path is the only credential. Returns 404 if the link is unknown and 410 if it is no longer available. Category: Missing Certificates (Public) Path parameters: token (string, required) Response fields: customerName (string, required) - The purchaser's name. sellerName (string, required) - The business that requested the certificate. jurisdictions (string[], required) - Jurisdictions a certificate is needed for. jurisdictionStatuses (PublicMissingCertificateJurisdictionStatus[], required) - Per-jurisdiction coverage status. state (string, required) - The jurisdiction (US state code). status (string, required) - Coverage status for this jurisdiction. allowed values: pending, processing, satisfied, rejected reason (string) - Why the jurisdiction is not satisfied, when applicable. Response statuses: 200, 404, 410, 422 --- # Confirm uploaded certificates for a missing-certificate request POST /public/exemption-requests/{token}/missing-certificates/confirm-upload Source: https://docs.trykintsugi.com/reference/2026-07-21/confirm-uploaded-certificates-for-a-missing-certificate-request POST /public/exemption-requests/{token}/missing-certificates/confirm-upload Confirm uploaded certificates for a missing-certificate request Confirm that files issued by a prior upload-urls call finished uploading to S3, then run validation. Send the `certificateImportId`s from that call. Returns 404 if an id is not part of this request, and 410 if the link is no longer available. Category: Missing Certificates (Public) Path parameters: token (string, required) Request body: certificateImportIds (string[], required) - The certificateImportIds whose uploads completed successfully. Response fields: status (string, required) - Overall validation outcome across the confirmed uploads. allowed values: processing, satisfied, rejected reason (string) - Why the request is not satisfied, when applicable. results (PublicMissingCertificateJurisdictionResult[], required) - Per-upload validation outcomes. certificateImportId (string, required) - The confirmed upload this result is for. exemptionId (string) - The exemption created from this certificate, when satisfied. status (string, required) - Validation outcome for this upload. allowed values: processing, satisfied, rejected reason (string) - Why the upload was rejected, when applicable. Response statuses: 200, 400, 404, 410, 422 --- # Request presigned upload urls for a missing-certificate request POST /public/exemption-requests/{token}/missing-certificates/upload-urls Source: https://docs.trykintsugi.com/reference/2026-07-21/request-presigned-upload-urls-for-a-missing-certificate-request POST /public/exemption-requests/{token}/missing-certificates/upload-urls Request presigned upload urls for a missing-certificate request Request one presigned S3 upload target per file for a missing-certificate request. POST each file to its target, then call confirm-upload. Returns 400 if a file type is not supported, 404 if the link is unknown, and 410 if it is no longer available. Category: Missing Certificates (Public) Path parameters: token (string, required) Request body: files (PublicUploadFile[], required) - The files to request upload targets for. fileName (string, required) - Original filename including extension. mimeType (string, required) - Media type of the file. Response fields: files (PublicUploadUrl[], required) - One presigned upload target per requested file. fileName (string, required) - The file name this upload target is for. certificateImportId (string, required) - Id to send back to confirm-upload once the S3 POST succeeds. uploadUrlConfig (PublicPresignedUpload, required) - The presigned S3 POST for this file. url (string, required) - The S3 endpoint to POST the file to. fields (PublicUploadField[], required) - Form fields to include in the multipart POST, verbatim, alongside the file part. Send every entry as a form field named `key` with its `value`. key (string, required) - The form field name. value (string, required) - The form field value to send verbatim. Response statuses: 200, 400, 404, 410, 422 --- # Request presigned upload urls for an exemption request POST /public/exemption-requests/{token}/upload-urls Source: https://docs.trykintsugi.com/reference/2026-07-21/request-presigned-upload-urls-for-an-exemption-request POST /public/exemption-requests/{token}/upload-urls Request presigned upload urls for an exemption request Request one presigned S3 upload target per file. POST each file to its target, then call confirm-upload with the returned `certificateImportId`s. Returns 400 if a file type is not supported, 404 if the link is unknown, and 410 if it is no longer available. Category: Exemption Requests (Public) Path parameters: token (string, required) Request body: files (PublicUploadFile[], required) - The files to request upload targets for. fileName (string, required) - Original filename including extension. mimeType (string, required) - Media type of the file. Response fields: files (PublicUploadUrl[], required) - One presigned upload target per requested file. fileName (string, required) - The file name this upload target is for. certificateImportId (string, required) - Id to send back to confirm-upload once the S3 POST succeeds. uploadUrlConfig (PublicPresignedUpload, required) - The presigned S3 POST for this file. url (string, required) - The S3 endpoint to POST the file to. fields (PublicUploadField[], required) - Form fields to include in the multipart POST, verbatim, alongside the file part. Send every entry as a form field named `key` with its `value`. key (string, required) - The form field name. value (string, required) - The form field value to send verbatim. Response statuses: 200, 400, 404, 410, 422 --- # Download a report via an emailed link GET /public/reports/downloads/{download_token} Source: https://docs.trykintsugi.com/reference/2026-07-21/download-a-report-via-an-emailed-link GET /public/reports/downloads/{download_token} Download a report via an emailed link Redirect to a short-lived presigned URL for a completed report. The link token in the path is the only credential; no Api-Key or bearer token is needed or accepted. Returns 404 if the link is unknown or the report is not yet ready, and 410 if the link has expired. Category: Reports (Public) Path parameters: download_token (string, required) Response statuses: 307, 404, 410, 422 --- # Get a jurisdiction's registration form GET /registration-jurisdiction-fields Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-jurisdiction-s-registration-form GET /registration-jurisdiction-fields Get a jurisdiction's registration form Return the fields a jurisdiction requires on a registration: a JSON Schema plus UI metadata for rendering the form. This is reference data shared by every organization, but a valid credential is still required. The schema's property names match the `jurisdictionSpecificFields` you send on a registration create. When the jurisdiction needs no jurisdiction-specific fields, `defaultForm` is `true`, the schema is an empty object and `metadata` is `null`. Category: Registrations Query parameters: countryCode (string, required) - ISO 3166-1 alpha-2 country code. stateCode (string, required) - State or province code. Response fields: countryCode (string, required) - ISO 3166-1 alpha-2 country code the schema is for, such as `US`, `CA` or `GB`. stateCode (string, required) - State or province code the schema is for. defaultForm (boolean, required) - `true` when this jurisdiction requires no jurisdiction-specific fields and the generic registration form should be used. `jurisdictionFieldsJsonSchema` is then an empty object and `metadata` is `null`. jurisdictionFieldsJsonSchema (object, required) - JSON Schema for the fields this jurisdiction accepts under `jurisdictionSpecificFields`. Property names are camelCase. An empty object when `defaultForm` is `true`. metadata (JurisdictionFormMetadata) - UI metadata for rendering the form. `null` when `defaultForm` is `true`. title (string, required) - Heading to show above the form. portalWebsiteUrl (string) - Tax authority portal this jurisdiction's credentials sign in to. `null` when none is recorded. portalWebsiteLabel (string) - Display label for `portalWebsiteUrl`. `null` when none is recorded. helpArticles (HelpArticle[]) - Help-center links to guide the user through this jurisdiction. label (string, required) - Human-readable title of the help article. url (string, required) - Link to the help article. sstBannerEnabled (boolean, required) - Whether the form should show the Streamlined Sales Tax banner for this jurisdiction. filingFrequencies (string[]) - Filing frequencies to offer for this jurisdiction. Empty when the full standard set applies. securityQuestionsEnabled (boolean, required) - Whether the form collects security questions for this jurisdiction. [truncated, see the reference page] --- # List registration jurisdictions GET /registration-jurisdictions Source: https://docs.trykintsugi.com/reference/2026-07-21/list-registration-jurisdictions GET /registration-jurisdictions List registration jurisdictions List the country/state jurisdictions your organizations hold registrations in. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to narrow to one. The whole set is returned in one response. `status` takes a comma-separated list and keeps only jurisdictions with a registration in one of those statuses; omit it to include every status. Category: Registrations Query parameters: status (string) - Comma-separated lifecycle statuses; keeps jurisdictions matching any of them. Response fields: jurisdictions (RegistrationJurisdiction[], required) - Distinct country/state jurisdictions across the organizations in scope, ordered by country then state. Streamlined Sales Tax registrations are excluded. countryCode (string, required) - ISO 3166-1 alpha-2 country code the registration is held in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code within `countryCode`. An empty string for a country-level jurisdiction. stateName (string) - Display name of the state or province. An empty string for a country-level jurisdiction. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Preview registering a jurisdiction POST /registration-preflights Source: https://docs.trykintsugi.com/reference/2026-07-21/preview-registering-a-jurisdiction POST /registration-preflights Preview registering a jurisdiction Report what a DIRECT_REQUEST `POST /registrations` for a jurisdiction would do, without creating anything. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to say which organization it is for `result` is OK when a new registration would be opened, ABSORBED when an existing sales-tax registration would cover the jurisdiction instead (returned as `registration`), PLAN_UPGRADE_REQUIRED when the organization's plan does not include the registration, or SALES_TAX_REGISTRATION_REQUIRED when a retail delivery fee registration needs an active sales-tax registration in the jurisdiction first It assumes the jurisdiction has a nexus, like the register dialog, which only previews jurisdictions the organization is exposed in. A jurisdiction with no nexus reports OK This is read-only: it stores nothing and never creates a registration. Category: Registrations Request body: countryCode (string, required) - ISO 3166-1 alpha-2 country code to check, such as `US`, `CA` or `GB`. stateCode (string) - State or province code within `countryCode`. Omit it for a country-level check. taxType (PublicTaxTypeEnum) - Which taxes the prospective registration would cover. allowed values: SALES_TAX, USE_TAX, SALES_AND_USE_TAX, RETAIL_DELIVERY_FEE Response fields: result (PublicRegisterPreflightResultEnum, required) - OK to open a new registration, ABSORBED when a sales-tax registration would cover it, PLAN_UPGRADE_REQUIRED when the plan does not include it, or SALES_TAX_REGISTRATION_REQUIRED when the retail delivery fee needs an active sales-tax registration first. allowed values: OK, ABSORBED, PLAN_UPGRADE_REQUIRED, SALES_TAX_REGISTRATION_REQUIRED registration (Registration) - The existing sales-tax registration that would absorb this one. Present only when `result` is ABSORBED, `null` otherwise. id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. organizationName (string) - Display name of the organization the registration belongs to. `null` when the organization has no name set. Sort a list by it with `sort=organizationName`. [truncated, see the reference page] --- # List registrations GET /registrations Source: https://docs.trykintsugi.com/reference/2026-07-21/list-registrations GET /registrations List registrations List tax registrations, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Every filter takes a comma-separated list and matches any of the values you send. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` or `previousCursor` to page; `hasMore` and `hasPrevious` report whether a page exists that way. Pass `sort` and `order` to order the list; omit `sort` to keep the default order. None of the sort keys is index-backed, so sorting a large organization's registrations sorts the whole matching set. A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Registrations Query parameters: sort (PublicRegistrationSortEnum) - Field to sort by. Omit to keep the default ordering. `organizationName` orders by the owning organization's display name, which is useful only on a portfolio-wide list. None of the keys is index-backed, so sorting sorts the whole matching set on a large organization. allowed values: organizationName, countryCode, stateCode, registrationDate, status order (PublicRegistrationSortOrder) - Sort direction. Applies only when `sort` is set. Defaults to `asc`. allowed values: asc, desc status (string) - Comma-separated lifecycle statuses; matches any of them. countryCode (string) - Comma-separated ISO 3166-1 alpha-2 country codes; matches any of them. stateCode (string) - Comma-separated state or province codes; matches any of them. Combine it with `countryCode` when a code is not unique across countries. filingFrequency (string) - Comma-separated filing frequencies; matches any of them. taxType (string) - Comma-separated tax types; matches any of them. limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Registration[], required) - The registrations on this page. id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. [truncated, see the reference page] --- # Create a registration POST /registrations Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-registration POST /registrations Create a registration Register in one jurisdiction or record a registration you already hold. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to say which organization it belongs to `registrationImportType` chooses the kind of registration. REGULAR is the default and is a direct registration identified by `countryCode` and `stateCode`. OSS is an EU One Stop Shop scheme, identified by its member state instead. SST is the single Streamlined Sales Tax registration an organization may hold, covering the member states at once DIRECT_REQUEST asks Kintsugi to obtain a registration you do not yet hold, rather than recording one you already have. Kintsugi resolves the jurisdiction from `countryCode`, `stateCode` and `taxType`, opens the registration in PROCESSING for its team to complete, and requires a paid plan that includes managed registrations. A free plan is refused with 403 PLAN_UPGRADE_REQUIRED. A paid plan that does not include managed registrations is refused with 403 FORBIDDEN. Use `POST /registration-preflights` first to see whether an existing registration would cover it An SST registration is write-only on this surface. It records the organization's Streamlined Sales Tax enrollment and sign-in, and unlike a REGULAR or OSS registration it is not returned by `GET /registrations/{registrationId}` or the list Category: Registrations Request body: registrationImportType (string) - Discriminates this from an SST or EU OSS registration. Defaults to REGULAR. countryCode (string, required) - ISO 3166-1 alpha-2 country code to register in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code to register in, within `countryCode`. Omit it for a country-level registration. stateName (string) - Display name of the state or province. Omit it and Kintsugi derives it from `countryCode` and `stateCode`. filingFrequency (PublicFilingFrequencyEnum, required) - How often returns should be filed. Send UNKNOWN when the jurisdiction has not assigned one yet; Kintsugi replaces it once it does. allowed values: UNKNOWN, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY, ANNUAL_FISCAL_YEAR, SEMI_MONTHLY, BI_MONTHLY, FOUR_MONTHLY, QUARTERLY_PREPAYMENT registrationDate (string) - Date the registration takes effect in the jurisdiction, as YYYY-MM-DD. Omit it when the jurisdiction has not assigned one. [truncated, see the reference page] --- # Summarize registrations by status GET /registrations/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-registrations-by-status GET /registrations/summary Summarize registrations by status Count registrations by lifecycle status across every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` header to narrow to one. A status with no registrations is omitted rather than reported as zero. Streamlined Sales Tax registrations are excluded, matching the list. Category: Registrations Response fields: total (integer, required) - Total registrations in scope, across every status. Excludes Streamlined Sales Tax registrations, which are not listed on this surface. statusCounts (RegistrationStatusCount[], required) - One entry per status present in scope. A status with no registrations is omitted rather than reported as zero. status (PublicRegistrationStatusEnum, required) - The lifecycle status this count is for. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED count (integer, required) - Number of registrations in scope with this status. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Get a registration by id GET /registrations/{registration_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-registration-by-id GET /registrations/{registration_id} Get a registration by id Fetch a single tax registration by id. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. organizationName (string) - Display name of the organization the registration belongs to. `null` when the organization has no name set. Sort a list by it with `sort=organizationName`. countryCode (string, required) - ISO 3166-1 alpha-2 country code the registration is held in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code the registration is held in, within `countryCode`. An empty string for a country-level registration. stateName (string) - Display name of the state or province. An empty string for a country-level registration. status (PublicRegistrationStatusEnum, required) - Lifecycle status. Only a REGISTERED or SELF_MANAGED registration has returns filed against it; the others are in progress, wound down, or retained for reporting. allowed values: REGISTERED, PROCESSING, UNREGISTERED, DEREGISTERING, DEREGISTERED, CANCELLED, VALIDATING, AWAITING_CLARIFICATION, SELF_MANAGED isPreCollecting (boolean) - True on a PROCESSING registration that marks the organization as collecting tax in the jurisdiction ahead of registration details. Always false on any other status. registrationType (PublicRegistrationTypeEnum, required) - Whether the registration is an EU One Stop Shop scheme covering several member states, or a direct registration with one jurisdiction. allowed values: EU_OSS, OTHER registrationCategory (PublicRegistrationCategoryEnum, required) - How the registration was established: REGULAR for one Kintsugi filed, IMPORTED for one you already held and brought across, DEREGISTRATION for one being wound down. allowed values: REGULAR, IMPORTED, DEREGISTRATION [truncated, see the reference page] --- # Update a registration PATCH /registrations/{registration_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-registration PATCH /registrations/{registration_id} Update a registration Update a registration. This is a partial update: a property you leave out is unchanged, and one you send as `null` is cleared. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. The jurisdiction, the lifecycle status and the sign-in credentials are not editable here: a registration cannot be moved to another jurisdiction, and the other two are separate operations. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Request body: filingFrequency (PublicFilingFrequencyEnum) - How often returns should be filed. Omit to leave unchanged; send a value to replace. allowed values: UNKNOWN, MONTHLY, QUARTERLY, SEMI_ANNUALLY, ANNUALLY, ANNUAL_FISCAL_YEAR, SEMI_MONTHLY, BI_MONTHLY, FOUR_MONTHLY, QUARTERLY_PREPAYMENT registrationDate (string) - Date the registration takes effect in the jurisdiction, as YYYY-MM-DD. Omit to leave unchanged; send `null` to clear. registrationEmail (string) - Email address the jurisdiction has on file. Omit to leave unchanged; send an empty string or `null` to clear it. createFilingsFrom (string) - First period to generate filings for, as YYYY-MM-DD. Omit to leave unchanged; send `null` to clear. registrationRequested (string) - When the registration was submitted to the jurisdiction. Omit to leave unchanged; send `null` to clear. registrationCompleted (string) - When the jurisdiction confirmed the registration. Omit to leave unchanged; send `null` to clear. deregistrationRequested (string) - When deregistration was submitted to the jurisdiction. Omit to leave unchanged; send `null` to clear. deregistrationCompleted (string) - When the jurisdiction confirmed the deregistration. Omit to leave unchanged; send `null` to clear. autoRegistered (boolean) - Whether the registration was completed without manual intervention. Omit to leave unchanged; send `true` or `false` to replace. doNotFile (boolean) - Whether returns are suppressed for this registration. When true, Kintsugi tracks it but does not file against it. Omit to leave unchanged; send `true` or `false` to replace. [truncated, see the reference page] --- # Upload an attachment for a registration POST /registrations/{registration_id}/attachments Source: https://docs.trykintsugi.com/reference/2026-07-21/upload-an-attachment-for-a-registration POST /registrations/{registration_id}/attachments Upload an attachment for a registration Attach a file to a registration in the resolved organization, as `multipart/form-data` with the file in the `file` part. Any file type is accepted, up to 10 MB. Returns the stored attachment's metadata. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, and 413 if the file exceeds the size limit. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: id (string, required) - Kintsugi's unique identifier for the stored attachment. fileName (string, required) - The uploaded file's name. mimeType (string, required) - The uploaded file's MIME type, as sent by the client. fileSizeBytes (integer, required) - The uploaded file's size in bytes. createdAt (string, required) - When the attachment was stored, as an RFC-3339 UTC timestamp. Response statuses: 201, 400, 401, 403, 404, 409, 413, 422 --- # Set a registration's credentials PUT /registrations/{registration_id}/credentials Source: https://docs.trykintsugi.com/reference/2026-07-21/set-a-registration-s-credentials PUT /registrations/{registration_id}/credentials Set a registration's credentials Set the stored sign-in credentials for a registration. Send a value for any of `username`, `password`, `pin`, `securityQuestions`, or `jurisdictionSpecificFields` to set it; a field you leave out (or send as `null`) is left unchanged. Sending `securityQuestions` replaces the stored set. `jurisdictionSpecificFields` accepts California `cdtfaThirdPartyAccessSecurityCode` and Idaho `accessCode` only. Credentials are write-only: this returns the registration, never the values you sent, which are readable only through the credentials reveal endpoint. Only an owner of the organization (or an API key scoped to it) may call it. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access; 403 if your credential may read the organization but is not permitted to change credentials. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Request body: username (string) - Username for the jurisdiction's portal. Omit it or send `null` to leave the stored username unchanged. Write-only: reveal it through the credentials reveal endpoint. password (string) - Password for the jurisdiction's portal, stored encrypted. Omit it or send `null` to leave the stored password unchanged. Write-only: reveal it through the credentials reveal endpoint. pin (string) - PIN for the jurisdiction's portal, where one is used, stored encrypted. Omit it or send `null` to leave the stored PIN unchanged. Write-only: reveal it through the credentials reveal endpoint. securityQuestions (PublicSecurityQuestion[]) - Security questions for the jurisdiction's portal, stored encrypted. Sending this replaces the stored set with the questions you send; omit it or send `null` to leave them unchanged. Write-only: reveal them through the credentials reveal endpoint. question (string, required) - The security question prompt shown by the jurisdiction portal. answer (string, required) - The answer to the security question. Write-only: reveal it through the credentials reveal endpoint. [truncated, see the reference page] --- # Reveal a registration's credentials POST /registrations/{registration_id}/credentials/reveal Source: https://docs.trykintsugi.com/reference/2026-07-21/reveal-a-registration-s-credentials POST /registrations/{registration_id}/credentials/reveal Reveal a registration's credentials Decrypt and return specific stored credentials for a registration. Name the fields to reveal in the request body; each must be one of `username`, `password`, `pin`, `security_questions`, `jurisdictionSpecificFields`. `jurisdictionSpecificFields` returns a map of the registration's decrypted jurisdiction secrets (for example California's CDTFA third-party access code or Idaho's TAP access code), gated to the registration's jurisdiction. A field you do not name, or one with nothing stored, comes back `null`, so the response never confirms which credentials exist beyond what you asked for. This is a privileged, audited operation: only an owner of the organization (or an API key scoped to it) may call it. The response is never cached (`Cache-Control: no-store`). Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists; 403 if your credential may read the organization but is not permitted to reveal credentials. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Request body: fields (PublicRegistrationCredentialField[], required) - Which stored credentials to decrypt and return. Each must be one of `username`, `password`, `pin`, `security_questions`, `jurisdictionSpecificFields`; any other value is rejected. A field you do not name comes back `null`, indistinguishable from one with nothing stored. allowed values: username, password, pin, security_questions, jurisdictionSpecificFields Response fields: username (string) - Decrypted username, when `username` was requested and one is stored. `null` otherwise. password (string) - Decrypted password, when `password` was requested and one is stored. `null` otherwise. pin (string) - Decrypted PIN, when `pin` was requested and one is stored. `null` otherwise. securityQuestions (PublicSecurityQuestion[]) - Decrypted security questions, when `security_questions` was requested and any are stored. `null` otherwise. question (string, required) - The security question prompt shown by the jurisdiction portal. answer (string, required) - The answer to the security question. Write-only: reveal it through the credentials reveal endpoint. [truncated, see the reference page] --- # Deregister a registration POST /registrations/{registration_id}/deregister Source: https://docs.trykintsugi.com/reference/2026-07-21/deregister-a-registration POST /registrations/{registration_id}/deregister Deregister a registration Begin deregistering a registration, moving it into the DEREGISTERING lifecycle status. Send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to say which organization it belongs to. The body must include `closureDate`, `reason`, and `finalReturnAcknowledged`. It may also include `requestId`, a client-minted id for this confirm attempt stored on the audit row. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. Returns 409 if the registration is in a lifecycle status it cannot be deregistered from. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration to deregister. Request body: closureDate (string, required) - Effective date the permit closes with the jurisdiction (YYYY-MM-DD). Past and future dates are accepted. Sets the final filing period end. reason (PublicDeregistrationReasonEnum, required) - Why the permit is closing: full business closure, or closing nexus in this one state. allowed values: FULL_BUSINESS_CLOSURE, CLOSING_NEXUS_IN_STATE finalReturnAcknowledged (boolean, required) - Must be true: confirms a final return is still owed for the closing period. requestId (string) - Optional client-minted id for this confirm attempt. When present, duplicate submits of the same gesture can be grouped. Response fields: id (string, required) - Kintsugi's unique identifier for the registration. organizationId (string, required) - Organization the registration belongs to. Send it as `Organization-Id` to scope a request to this registration. organizationName (string) - Display name of the organization the registration belongs to. `null` when the organization has no name set. Sort a list by it with `sort=organizationName`. countryCode (string, required) - ISO 3166-1 alpha-2 country code the registration is held in, such as `US`, `CA` or `GB`. stateCode (string) - State or province code the registration is held in, within `countryCode`. An empty string for a country-level registration. stateName (string) - Display name of the state or province. An empty string for a country-level registration. [truncated, see the reference page] --- # List a registration's OSS countries GET /registrations/{registration_id}/oss-countries Source: https://docs.trykintsugi.com/reference/2026-07-21/list-a-registration-s-oss-countries GET /registrations/{registration_id}/oss-countries List a registration's OSS countries List the EU member states an EU One Stop Shop registration covers. Searched across every organization your credential owns, so no selector is needed for a known id. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access, so the API never confirms an id exists. A registration that is not an EU OSS scheme returns an empty list. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response fields: ossCountries (RegistrationOssCountry[], required) - EU member states covered by this OSS registration. Empty for a registration that is not an EU OSS scheme. id (string, required) - Kintsugi's unique identifier for this OSS country enrollment. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the EU member state covered, such as `DE`, `FR` or `IT`. effectiveDate (string, required) - Date this member state became covered by the OSS registration, as YYYY-MM-DD. endDate (string) - Date this member state stopped being covered, as YYYY-MM-DD. `null` while the country is still covered. status (PublicOssCountryStatusEnum, required) - Whether the member state is currently covered (ACTIVE) or has been removed from the OSS registration (REMOVED). allowed values: ACTIVE, REMOVED Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Email a registration's password to yourself POST /registrations/{registration_id}/send-password Source: https://docs.trykintsugi.com/reference/2026-07-21/email-a-registration-s-password-to-yourself POST /registrations/{registration_id}/send-password Email a registration's password to yourself Send the registration's stored credentials to the email address on your own credential. Nothing is returned in the body, and the credentials are never exposed to the caller directly. Only an owner of the organization (or an API key scoped to it) may call it. Returns 404 if the registration does not exist or belongs to an organization your credential cannot access; 403 if your credential may read the organization but is not permitted; 400 if the registration has no credentials stored to send. Category: Registrations Path parameters: registration_id (string, required) - The unique identifier of the registration. Response statuses: 204, 400, 401, 403, 404, 409, 422 --- # Start a report job POST /reports/jobs Source: https://docs.trykintsugi.com/reference/2026-07-21/start-a-report-job POST /reports/jobs Start a report job Start generating a report for the resolved organization and return `202` with the job's id. The report is generated asynchronously: poll `GET /reports/jobs/{reportJobId}` for its status, then `GET /reports/jobs/{reportJobId}/download` once it is `READY`. `reportArgs` is shaped by `reportType`; an organization may have at most 5 report jobs queued or processing at once. Set `deliveryMethod` to `EMAIL` to get a download link by email instead of fetching it yourself. A `VAT_REPORT` job is read back as JSON from `GET /reports/jobs/{reportJobId}/result`; it needs VAT accounts payable enabled on the organization (else `403`) and a DE, GB, CZ, ES, or SG filing (else `400`). Category: Reports Request body: deliveryMethod (ReportDeliveryMethodEnum) - `DOWNLOAD` (default) stores the report for `GET /reports/jobs/{reportJobId}/download`. `EMAIL` emails a download link to the address of the user behind your credential; the address cannot be set in the request. Not available for `BULK_FILING_REPORTS` or `VAT_REPORT`. allowed values: DOWNLOAD, EMAIL reportType (string, required) - Which report to generate. reportArgs (NexusReportArgs) - No filters for this report type. Response fields: reportJobId (string, required) - Id of the new report job. status (PublicReportJobStatusEnum) - Always `QUEUED` on creation. allowed values: QUEUED, PROCESSING, READY, FAILED reportType (PublicReportTypeEnum, required) - The report type this job will generate, echoed back from the request. allowed values: NEXUS, TRANSACTIONS_SUMMARY, TRANSACTIONS_DETAILS, FILINGS_SUMMARY, FILINGS, FILING_DETAILS, BULK_FILING_REPORTS, PRODUCTS, COLLECTED_TRANSACTIONS, VAT_REPORT deliveryMethod (ReportDeliveryMethodEnum) - How the report will be delivered, echoed back from the request. allowed values: DOWNLOAD, EMAIL Response statuses: 202, 400, 401, 403, 404, 422, 429, 503 --- # Get a report job's status GET /reports/jobs/{report_job_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-report-job-s-status GET /reports/jobs/{report_job_id} Get a report job's status Get the status of a report job you started. Searched across every organization your credential owns, so no selector is needed for a known id. A job you do not own answers `404`, identical to one that does not exist. Category: Reports Path parameters: report_job_id (string, required) - Id of the report job. Response fields: reportJobId (string, required) - Id of the report job. status (PublicReportJobStatusEnum, required) - Current lifecycle state. Once `READY`, fetch `GET /reports/jobs/{reportJobId}/download` for a download link. allowed values: QUEUED, PROCESSING, READY, FAILED errorMessage (string) - Why the job failed. Null unless status is `FAILED`. Response statuses: 200, 400, 401, 403, 404, 422 --- # Get a report job's download link GET /reports/jobs/{report_job_id}/download Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-report-job-s-download-link GET /reports/jobs/{report_job_id}/download Get a report job's download link Get a presigned download URL for a `READY` report job. Searched across every organization your credential owns. A job you do not own answers `404`, identical to one that does not exist; a job that is not yet `READY` answers `409`. Category: Reports Path parameters: report_job_id (string, required) - Id of the report job. Response fields: url (string, required) - Presigned URL to fetch the report file. expiresInSeconds (integer, required) - How long `url` stays valid, in seconds. filename (string, required) - Suggested filename for the downloaded report. Response statuses: 200, 400, 401, 403, 404, 409, 422, 500 --- # Get a report job's result GET /reports/jobs/{report_job_id}/result Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-report-job-s-result GET /reports/jobs/{report_job_id}/result Get a report job's result Get the JSON result of a `READY` report job whose report is viewed rather than downloaded (today, `VAT_REPORT`). Searched across every organization your credential owns. A job you do not own answers `404`, identical to one that does not exist; a job of a downloadable report type answers `400` (use `GET /reports/jobs/{reportJobId}/download`); a job that is not yet `READY` answers `409`. Category: Reports Path parameters: report_job_id (string, required) - Id of the report job. Response fields: reportJobId (string, required) - Id of the report job. reportType (PublicReportTypeEnum, required) - Which report the job generated. allowed values: NEXUS, TRANSACTIONS_SUMMARY, TRANSACTIONS_DETAILS, FILINGS_SUMMARY, FILINGS, FILING_DETAILS, BULK_FILING_REPORTS, PRODUCTS, COLLECTED_TRANSACTIONS, VAT_REPORT vatReport (VatReport) - The VAT return report. Set when `reportType` is `VAT_REPORT`. filingId (string, required) - Id of the filing the report covers. organizationId (string, required) - Id of the organization that owns it. countryCode (string, required) - ISO 3166-1 alpha-2 country code of the filing's country, such as `US`, `CA` or `GB`. returnForm (string, required) - Return form the boxes follow. returnFormLabel (string, required) - Display name of the return form. filingEntityRegistrationNumber (string, required) - VAT registration number of the filing entity. Empty if unknown. periodStart (string, required) - First day of the filing period. periodEnd (string, required) - Last day of the filing period. currency (string, required) - ISO-4217 code every amount is in. sections (VatReturnSection[], required) - Return-form sections. sectionLabel (string, required) - Label of the section. boxes (VatReturnBox[], required) - Boxes in this section. boxCode (string, required) - Box number or code on the return form. boxLabel (string, required) - Label of the box on the return form. amount (string, required) - Box amount, in the report currency. category (string, required) - `OUTPUT_VAT`, `INPUT_VAT`, `NET` or `INFORMATIONAL`. sourceTransactionCount (integer, required) - How many transactions contribute to this box. summary (VatReturnSummary, required) - Totals across the return. totalOutputVat (string, required) - VAT charged on sales. [truncated, see the reference page] --- # Estimate tax on a transaction POST /tax-estimations Source: https://docs.trykintsugi.com/reference/2026-07-21/estimate-tax-on-a-transaction POST /tax-estimations Estimate tax on a transaction Estimate the tax due on a transaction without recording it. Nothing is stored and the estimate is not retrievable afterwards, so send the same request again to price it again. The estimate is computed for exactly one organization: send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector, which a credential owning more than one organization must do. Each line names either an `externalProductId` you have already created or a `productCategory` and `productSubcategory` pair, which is priced without creating a product. An `externalProductId` is unique only within a connection, so when the same id exists in more than one of your connections, send a `Connection-Id` to price against that connection's product; without one an ambiguous id returns 400. Addresses are validated as part of the estimate: an address that cannot be validated returns 400, one in a country Kintsugi does not cover returns 422, and an address-validation outage returns 503. Tax is only due where an active registration covers the destination, so `hasActiveRegistration` false comes back with every amount at zero. Set `simulateActiveRegistration` to see what the transaction would be taxed at if you were registered there. Category: Tax Estimations Request body: externalId (string, required) - Your identifier for the transaction. Echoed on the response. date (string, required) - When the transaction takes place. Rates in force on this date are the ones applied. currency (string, required) - Currency of every amount on the request, ISO 4217. An unrecognized code returns 400. simulateActiveRegistration (boolean) - Set true to price the transaction as though you were registered in the destination jurisdiction. Use it to preview what registering would cost your buyers; leave it false to see what you owe today. customer (TaxEstimateCustomer) - The buyer. `null` when you have no buyer to attribute the transaction to, in which case no customer-level exemption applies. externalId (string) - Your stable identifier for the buyer. Defaults to an empty string when omitted. When it matches a customer Kintsugi already holds, that customer's exemptions and tax registrations are applied to the estimate. name (string) - Buyer name. companyName (string) - Registered or legal business name. email (string) - Contact email address. [truncated, see the reference page] --- # List transactions GET /transactions Source: https://docs.trykintsugi.com/reference/2026-07-21/list-transactions GET /transactions List transactions List transactions, keyset-paginated. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Archived and duplicate transactions are never returned. Filter with the query params (`countryCode`, `stateCode`, `dateFrom`, `collectedTax`, `includeRefunds`, `customerId`, and the existing list filters) and sort with `sort` / `order` (default `date` descending, so newest first). A cursor is only valid for the sort, the filters AND the organization scope it was issued under, including any selector header: change any of them and start again from the first page. Category: Transactions Query parameters: sort (PublicTransactionSortEnum) - Field to sort by. Defaults to `date`. allowed values: date, totalAmount, status, country order (PublicTransactionSortOrder) - Sort direction. Defaults to `desc`, so newest first. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. startDate (string) - Include transactions on or after this date (YYYY-MM-DD). endDate (string) - Include transactions on or before this date (YYYY-MM-DD). status (string) - Comma-separated transaction statuses; matches any of them. refundStatus (string) - Comma-separated refund statuses; matches any of them. source (string) - Comma-separated source systems; matches any of them. type (string) - Comma-separated transaction type filters; matches any of them. `CREDIT_NOTE` groups every credit-note type; `SALES_ORDER` filters sales orders. addressStatus (string) - Comma-separated address statuses; matches any of them. connectionId (string) - Comma-separated connection ids; matches any of them. This filters rows by connection. To restrict which organization is read, send the `Connection-Id` header instead. country (string) - Comma-separated ISO-3166 country codes; matches any of them. state (string) - Comma-separated state or province codes; matches any of them. direction (PublicTransactionDirectionEnum) - Restrict to sales or purchases. Omit to return both, matching the unfiltered list. allowed values: SALE, PURCHASE [truncated, see the reference page] --- # Create a transaction POST /transactions Source: https://docs.trykintsugi.com/reference/2026-07-21/create-a-transaction POST /transactions Create a transaction Create a transaction for the resolved organization. Accepted rather than created: tax is calculated asynchronously, so `totalTaxAmountCalculated` and the per-line `taxItems` populate shortly after this returns. `GET /transactions/{id}` can answer `404` for a short time after this returns. Once the transaction can be read, tax may still be calculating (`processingStatus` `QUEUED`); poll for the amounts rather than treating that first `404` as failure. Set `type` to `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE` and send `originalTransactionId` to reverse a pending, committed, or partially refunded sale. The credit note inherits the original transaction's customer, addresses and source; send the line items to credit in `items`, each carrying the `externalId` of the original line. Reversing a transaction you do not own answers `404`, identical to a transaction that does not exist. Re-POSTing the same credit-note external id against the same parent returns the stored credit note (same as a successful create) rather than a conflict. The same external id against a different parent still conflicts. Category: Transactions Request body: externalId (string, required) - Your stable identifier for the transaction. Re-sending the same one updates the existing transaction rather than creating a second. date (string, required) - When the transaction occurred. This drives which filing period it lands in, so send the real transaction time, not the time of the call. type (PublicTransactionTypeEnum) - Kind of transaction. `SALE` records a sale; `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE` with `originalTransactionId` reverses a pending, committed, or partially refunded sale. The stored type is derived from the amount credited, so it can differ from the one you send. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION originalTransactionId (string) - The sale being reversed. It must be pending, committed, or partially refunded. Required when `type` is a credit-note type and must be omitted for a `SALE`. The credit note inherits the original's customer, addresses and source, so send only the lines to credit in `items`. currency (PublicCurrencyEnum, required) - ISO-4217 currency of every amount sent. [truncated, see the reference page] --- # Archive a transaction POST /transactions/archive Source: https://docs.trykintsugi.com/reference/2026-07-21/archive-a-transaction POST /transactions/archive Archive a transaction Archive a transaction for the resolved organization. One-way: an archived transaction is excluded from every read on this API and cannot be restored, and its sales stop counting toward nexus. Archiving a transaction you do not own answers `404`, identical to one that does not exist; a locked or already-filed transaction answers `409`. Category: Transactions Request body: transactionId (string, required) - Id of the transaction to archive. Response fields: id (string, required) - Id of the transaction that was archived. archived (boolean) - Always `true`. Archiving is one-way and cannot be undone. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List transactions with a blank address GET /transactions/blank-addresses Source: https://docs.trykintsugi.com/reference/2026-07-21/list-transactions-with-a-blank-address GET /transactions/blank-addresses List transactions with a blank address List transactions that have no address yet, newest first, keyset-paginated, across every organization you own; narrow with `Organization-Id`, `Connection-Id` or `Entity-Id`. Only committed, non-marketplace transactions dated 2018 or later are listed, the same rows the blank-address count uses. A cursor is only valid for its search and scope. Category: Transactions Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. Response fields: items (Transaction[], required) - The transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID direction (PublicTransactionDirectionEnum, required) - Whether the organization made the sale or made the purchase. Both are returned, so filter on this if you only want one side. allowed values: SALE, PURCHASE customerId (string) - Kintsugi customer this transaction is attributed to. A sale with no customer identity (marketplace, point-of-sale) is attributed to the organization's shared unattributed-sales customer, which reads back with a `null` `externalId`. Check that before treating one `customerId` as one buyer. [truncated, see the reference page] --- # Export a transaction report POST /transactions/export Source: https://docs.trykintsugi.com/reference/2026-07-21/export-a-transaction-report POST /transactions/export Export a transaction report Kick off an asynchronous transaction report for the resolved organization and return `202` with the export's id. `SUMMARY` is aggregated figures; `DETAILS` is one row per transaction; `COLLECTED` is imported-tax sales in a jurisdiction. `deliveryMethod` chooses how you get it: `EMAIL` emails it to `email` when ready (a bearer session may omit `email` and use the signed-in user); `DOWNLOAD` stores it and you poll `GET /transactions/exports/{exportId}` for a presigned link (so `email` must be omitted). An `EMAIL` export for an organization that has disabled email delivery answers `400`. Category: Transactions Request body: deliveryMethod (TransactionExportDelivery, required) - How to deliver the report. `EMAIL` emails it to `email` when ready; `DOWNLOAD` stores it and you poll `GET /transactions/exports/{exportId}` for a presigned link. allowed values: EMAIL, DOWNLOAD reportType (TransactionReportType, required) - Which report to generate. `SUMMARY` is aggregated figures; `DETAILS` is one row per transaction; `COLLECTED` is imported-tax sales in a jurisdiction (the collected-tax drawer). allowed values: SUMMARY, DETAILS, COLLECTED email (string) - Email address the report is delivered to. Required when `deliveryMethod` is `EMAIL` unless the caller is a bearer session (which defaults to the signed-in user). Must be omitted when `deliveryMethod` is `DOWNLOAD`. countryCode (string) - Restrict the report to this ISO 3166-1 alpha-2 country code, such as `US`, `CA` or `GB`. Required when `reportType` is `COLLECTED`. stateCode (string) - Restrict the report to this state or province code. When `reportType` is `COLLECTED`, `FD` (federal nexus sentinel) is not applied as a state filter. startDate (string) - Include transactions on or after this date (YYYY-MM-DD). endDate (string) - Include transactions on or before this date (YYYY-MM-DD). Applies to `SUMMARY`, `DETAILS`, and `COLLECTED`. includeInvalidAddresses (boolean) - Include transactions with invalid addresses. Applies to the `DETAILS` report only; ignored for `SUMMARY` and `COLLECTED`. includeRefunds (boolean) - When `reportType` is `COLLECTED`, include credit notes with nonzero imported tax. Ignored for `SUMMARY` and `DETAILS`. Response fields: [truncated, see the reference page] --- # Get an export's status GET /transactions/exports/{export_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-an-export-s-status GET /transactions/exports/{export_id} Get an export's status Get the status of an export you started, and, once a `DOWNLOAD` export is `READY`, a presigned `downloadUrl` to fetch it. `downloadUrl` is `null` while the export is in progress and for an `EMAIL` export, which is delivered by email instead. Searched across every organization your credential owns; an export you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: export_id (string, required) - The id of the export job. Response fields: exportId (string, required) - Id of the export job. status (TransactionExportStatus, required) - Lifecycle state. `QUEUED` and `PROCESSING` are in progress; `READY` is done; `FAILED` could not be generated. allowed values: QUEUED, PROCESSING, READY, FAILED deliveryMethod (TransactionExportDelivery, required) - How the report is delivered. allowed values: EMAIL, DOWNLOAD downloadUrl (string) - Presigned URL to download the report. Non-`null` only when `status` is `READY` and `deliveryMethod` is `DOWNLOAD`; `null` otherwise, including for an `EMAIL` export, which is delivered by email rather than here. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List a filing's transactions GET /transactions/filings/{filing_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/list-a-filing-s-transactions GET /transactions/filings/{filing_id} List a filing's transactions List the transactions assigned to a filing, keyset-paginated the same way as `GET /transactions`. Covers every organization your credential owns. A filing id you do not own, or that does not exist, reads as an empty page rather than `404`, matching an owned filing with no transactions. Category: Transactions Path parameters: filing_id (string, required) - Id of the filing whose transactions to list. Query parameters: sort (PublicTransactionSortEnum) - Field to sort by. Defaults to `date`. allowed values: date, totalAmount, status, country order (PublicTransactionSortOrder) - Sort direction. Defaults to `desc`, so newest first. allowed values: asc, desc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (Transaction[], required) - The transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID direction (PublicTransactionDirectionEnum, required) - Whether the organization made the sale or made the purchase. Both are returned, so filter on this if you only want one side. allowed values: SALE, PURCHASE [truncated, see the reference page] --- # List transactions with an invalid address GET /transactions/invalid-addresses Source: https://docs.trykintsugi.com/reference/2026-07-21/list-transactions-with-an-invalid-address GET /transactions/invalid-addresses List transactions with an invalid address List transactions that need an address fix, keyset-paginated, across every organization you own; narrow with `Organization-Id`, `Connection-Id` or `Entity-Id`. Includes transactions marked invalid and verified ones whose US or unknown-country ship-to address is still invalid. A cursor is only valid for its sort, filters and scope. Category: Transactions Query parameters: sort (PublicInvalidAddressSortEnum) - `usFirst` (default) lists US addresses first, then other countries in country order, then rows with no country. `countryAsc` and `countryDesc` order by country, with no-country rows last. Newest first breaks ties. allowed values: usFirst, countryAsc, countryDesc limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. country (string) - ISO-3166 country code of the invalid address. hasCountry (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a country. hasState (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a state. hasCity (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a city. hasCounty (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a county. hasPostalCode (boolean) - Keep rows whose invalid address has (`true`) or lacks (`false`) a postal code. addressNotEmpty (boolean) - `true` keeps addresses with at least one of state, city, postal code or county; `false` keeps only fully empty ones. Response fields: items (Transaction[], required) - The transactions on this page. id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. [truncated, see the reference page] --- # Get connections' transaction date ranges GET /transactions/min-max-date Source: https://docs.trykintsugi.com/reference/2026-07-21/get-connections-transaction-date-ranges GET /transactions/min-max-date Get connections' transaction date ranges Get the earliest and latest non-archived, non-duplicate transaction date for each requested connection. Covers every organization your credential owns; a connection id you do not own, or that does not exist, reads `null`/`null` rather than being omitted or answering `404`, so it cannot be probed. Category: Transactions Query parameters: connectionIds (string, required) - Comma-separated connection ids to get date ranges for. Response fields: items (ConnectionDateRange[], required) - One entry per requested `connectionId`, in the order requested. A connection id you do not own, or with no matching transactions, reads `null`/`null` rather than being omitted. connectionId (string, required) - Id of the connection. minDate (string) - Earliest non-archived, non-duplicate transaction date for this connection, or `null` when it has none. maxDate (string) - Latest non-archived, non-duplicate transaction date for this connection, or `null` when it has none. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List transaction sources GET /transactions/sources Source: https://docs.trykintsugi.com/reference/2026-07-21/list-transaction-sources GET /transactions/sources List transaction sources List the distinct `source` values in use across your transactions. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Useful for a `source` filter dropdown of values that actually occur. Category: Transactions Response fields: items (TransactionSource[]) - Sources in use; empty when the scope has no transactions. value (string, required) - The `source` value, usable in the `source` list filter. label (string, required) - Human-readable display label for `value` (for example `Shopify`). Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # Summarize transactions GET /transactions/summary Source: https://docs.trykintsugi.com/reference/2026-07-21/summarize-transactions GET /transactions/summary Summarize transactions Aggregate counts and money totals over your transactions. Covers every organization your credential owns; send an `Organization-Id`, `Connection-Id` or `Entity-Id` selector to narrow to one. Accepts the same filters as `GET /transactions`, so the totals reflect the filtered set. Archived and duplicate transactions are excluded, and the money totals are sales only, matching the list. `incompleteAddressCount` is deliberately independent of the filters: it always counts every in-scope transaction whose address cannot be resolved. Category: Transactions Query parameters: search (string) - Free-text search over transaction id, externalId, externalFriendlyId, description and customer name. startDate (string) - Include transactions on or after this date (YYYY-MM-DD). endDate (string) - Include transactions on or before this date (YYYY-MM-DD). status (string) - Comma-separated transaction statuses; matches any of them. refundStatus (string) - Comma-separated refund statuses; matches any of them. source (string) - Comma-separated source systems; matches any of them. type (string) - Comma-separated transaction type filters; matches any of them. `CREDIT_NOTE` groups every credit-note type; `SALES_ORDER` filters sales orders. addressStatus (string) - Comma-separated address statuses; matches any of them. connectionId (string) - Comma-separated connection ids; matches any of them. This filters rows by connection. To restrict which organization is read, send the `Connection-Id` header instead. country (string) - Comma-separated ISO-3166 country codes; matches any of them. state (string) - Comma-separated state or province codes; matches any of them. direction (PublicTransactionDirectionEnum) - Restrict to sales or purchases. Omit to return both, matching the unfiltered list. allowed values: SALE, PURCHASE marketplace (boolean) - Restrict to marketplace (true) or non-marketplace (false) rows. filingId (string) - Restrict to transactions assigned to this filing. customerId (string) - Restrict to one customer's transactions by customer id. A customer outside your organizations returns an empty page. exempt (string) - Comma-separated exemption statuses; matches any of them. processingStatus (string) - Comma-separated processing statuses; matches any of them. [truncated, see the reference page] --- # Get a transaction by id GET /transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-transaction-by-id GET /transactions/{transaction_id} Get a transaction by id Fetch a single transaction by id. Searched across every organization your credential owns, so no selector is needed for a known id. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction. Response fields: id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID direction (PublicTransactionDirectionEnum, required) - Whether the organization made the sale or made the purchase. Both are returned, so filter on this if you only want one side. allowed values: SALE, PURCHASE customerId (string) - Kintsugi customer this transaction is attributed to. A sale with no customer identity (marketplace, point-of-sale) is attributed to the organization's shared unattributed-sales customer, which reads back with a `null` `externalId`. Check that before treating one `customerId` as one buyer. customerName (string) - Name of the customer this transaction is attributed to, or `null` when it has no customer or the customer has no name. customerExternalId (string) - Your identifier for the customer this transaction is attributed to, or `null` when it has no customer or the customer has no external id. connectionId (string) - Connection that synced this transaction, if any. source (string, required) - Origin system of the transaction. Sources outside the public set are reported as OTHER. [truncated, see the reference page] --- # Update a transaction PUT /transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-transaction PUT /transactions/{transaction_id} Update a transaction Replace a transaction's fields. The scalar fields (`date`, `totalAmount`, `description`, `currency`, `source`, `marketplace`) and the customer are overwritten with what you send. Line items are replaced: an item is matched to a stored one by `externalId`, a new `externalId` is added, and a stored line whose `externalId` you do not send is removed. Addresses are replaced per `type`: send a `SHIP_TO` to replace the ship-to, a `BILL_TO` to replace the bill-to; a type you omit is left as it was. The transaction's `type` is preserved and cannot be changed here. Tax is recalculated asynchronously, so `totalTaxAmountCalculated` and the per-line `taxItems` repopulate shortly after this returns. Updating a transaction you do not own answers `404`, identical to one that does not exist. A locked or already-filed transaction answers `409`. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to update. Request body: externalId (string, required) - Your stable identifier for the transaction. date (string, required) - When the transaction occurred. This drives which filing period it lands in, so send the real transaction time, not the time of the call. currency (PublicCurrencyEnum, required) - ISO-4217 currency of every amount sent. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) totalAmount (string) - Total transaction amount. addresses (TransactionAddressWrite[]) - Addresses for the transaction, replaced per `type`: a `SHIP_TO` you send replaces the stored ship-to, a `BILL_TO` the stored bill-to, and a type you omit is left unchanged. Jurisdiction is resolved from these, so an incomplete address means tax cannot be calculated accurately. type (PublicAddressTypeEnum, required) - Which party or location this address represents. Tax jurisdiction usually follows `SHIP_TO` (or `BILL_TO` when there is no ship-to). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM street1 (string) - First line of the street address. Omit or send `null` when unset. street2 (string) - Second line of the street address. Omit or send `null` when unset. city (string) - City or locality. Omit or send `null` when unset. county (string) - County or district. Omit or send `null` when unset. [truncated, see the reference page] --- # Update a credit note PATCH /transactions/{transaction_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-credit-note PATCH /transactions/{transaction_id} Update a credit note Update an existing credit note (a transaction whose `type` is `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE`). A true partial update: every field — `externalId`, `date`, `totalAmount`, `currency`, `description`, `marketplace`, `status` and `items` — is optional, and one you omit keeps the credit note's current stored value rather than being reset to a default. Send `status` as `CANCELLED` to reverse the credit note without deleting it; omitted, it stays whatever it already is (it does NOT default to `COMMITTED`). Calling this on a transaction that is not a credit note answers `400`; on one already `CANCELLED` also answers `400`. A locked or already-filed credit note answers `409`. Updating a credit note you do not own answers `404`, identical to one that does not exist. `PUT /transactions/{transactionId}` amends an ordinary transaction; it does not accept a credit note. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the credit note to update. Request body: externalId (string) - Your stable identifier for the credit note. Omit to keep the stored one. date (string) - When the credit note was issued. Omit to keep the stored date. status (string) - Lifecycle state of the credit note. Send `CANCELLED` to reverse it without deleting it; amounts and lines are otherwise unaffected. Omit to keep the current status — it does NOT default to `COMMITTED`. allowed values: PENDING, COMMITTED, CANCELLED currency (PublicCurrencyEnum) - ISO-4217 currency of every amount sent. Omit to keep the stored currency. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) totalAmount (string) - Total credit note amount. Omit to keep the stored amount — there is no default of `0.00`. description (string) - Free-text description of the credit note. Omit to keep the stored description. marketplace (boolean) - True for a marketplace or reseller credit note. Omit to keep the credit note's current marketplace flag. items (TransactionItemWrite[]) - Lines to credit. Each must carry the `externalId` of the original sale's line it reverses, exactly like the credit-note create. Omit to keep the credit note's stored lines. externalProductId (string, required) - Your identifier for the product on this line. [truncated, see the reference page] --- # Update a transaction's addresses PATCH /transactions/{transaction_id}/addresses Source: https://docs.trykintsugi.com/reference/2026-07-21/update-a-transaction-s-addresses PATCH /transactions/{transaction_id}/addresses Update a transaction's addresses Edit one or more of a transaction's addresses without touching its line items. Each address is upserted by its `type` (or `id`); a type you omit is left unchanged. Editing an address resets its validation, so `addressStatus` returns to `UNVERIFIED` and the address is re-verified on the next processing pass. Returns the updated transaction. Editing a transaction you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to edit. Request body: addresses (TransactionAddressEdit[], required) - Addresses to update on the transaction. Each is upserted by `type` (or `id`); a type you omit is left unchanged, and line items are never touched. Editing an address resets its validation, so it is re-verified on the next processing pass. type (PublicAddressTypeEnum, required) - Which address on the transaction to edit (its role). allowed values: BILL_TO, SHIP_TO, SHIP_FROM, BILL_FROM id (string) - Id of the address to edit. Omit to target the transaction's address of this `type`, creating one if it has none. street1 (string) - First line of the street address. Omit or send `null` to clear; send a value to set. street2 (string) - Second line of the street address. Omit or send `null` to clear; send a value to set. city (string) - City or locality. Omit or send `null` to clear; send a value to set. county (string) - County or district. Omit or send `null` to clear; send a value to set. state (string) - State or province code. Omit or send `null` to clear; send a value to set. postalCode (string) - Postal or ZIP code. Omit or send `null` to clear; send a value to set. fullAddress (string) - Single-line full address. Omit or send `null` to clear; send a value to set. phone (string) - Contact phone for the address. Omit or send `null` to clear; send a value to set. isUnincorporated (boolean) - When `true`, city-level tax rates are not applied to this address. Omit or send `null` to leave the stored value unchanged; send `false` to clear it. country (string) - ISO-3166 alpha-2 country code. Omit or send `null` to clear; send a value to set. Response fields: id (string, required) - Kintsugi's unique identifier for the transaction. [truncated, see the reference page] --- # Get a transaction's backlink GET /transactions/{transaction_id}/backlink Source: https://docs.trykintsugi.com/reference/2026-07-21/get-a-transaction-s-backlink GET /transactions/{transaction_id}/backlink Get a transaction's backlink Get a deep link to a transaction in its source system (for example NetSuite). Searched across every organization your credential owns. Answers `404` when not owned, and also when a backlink cannot be built (an unsupported source, no connection), so the two cannot be told apart. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction. Response fields: transactionId (string, required) - Id of the transaction. backlink (string, required) - URL to the transaction in the source system. connectionId (string, required) - Id of the connection the transaction was imported through. Response statuses: 200, 400, 401, 403, 404, 409, 422 --- # List related transactions GET /transactions/{transaction_id}/related Source: https://docs.trykintsugi.com/reference/2026-07-21/list-related-transactions GET /transactions/{transaction_id}/related List related transactions List the transactions related to one: the credit notes that reverse a sale, or the original sale a credit note reverses. Searched across every organization your credential owns, so no selector is needed for a known id. A transaction you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction. Response fields: items (RelatedTransaction[]) - Transactions related to the requested one; empty when there are none. id (string, required) - Kintsugi's unique identifier for the transaction. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. customerName (string) - Name of the customer the transaction is attributed to, if any. description (string) - Transaction description; an empty string when the source sent none. date (string, required) - When the transaction occurred. shopDate (string) - Calendar day the transaction occurred in the shop's timezone (`YYYY-MM-DD`), or `null` when the source did not report one. state (string) - Resolved state or province code, or `null` when none was resolved. status (PublicTransactionStatusEnum, required) - Lifecycle status of the transaction. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID totalAmount (string, required) - Total transaction amount. totalTaxAmountCalculated (string, required) - Total tax Kintsugi calculated. currency (PublicCurrencyEnum, required) - ISO-4217 currency the unconverted amounts are in. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) destinationCurrency (PublicCurrencyEnum) - Currency the converted amounts are in, or `null` when unconverted. allowed values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD (and 150 more, see the reference page) convertedTotalAmount (string) - `totalAmount` in the destination currency, or `null` when unconverted. convertedTotalTaxAmountCalculated (string) - `totalTaxAmountCalculated` in the destination currency, or `null` when unconverted. [truncated, see the reference page] --- # Mark or unmark a transaction as tax-only PATCH /transactions/{transaction_id}/tax-only Source: https://docs.trykintsugi.com/reference/2026-07-21/mark-or-unmark-a-transaction-as-tax-only PATCH /transactions/{transaction_id}/tax-only Mark or unmark a transaction as tax-only Reclassify a transaction as tax-only, or restore it. Set `taxOnly` to `true` to mark it: a `SALE` becomes `TAX_COLLECTION` and a credit note becomes `TAX_REFUND`. Set it to `false` to unmark: a `TAX_COLLECTION` restores to `SALE`, and a `TAX_REFUND` re-derives `FULL_CREDIT_NOTE` or `PARTIAL_CREDIT_NOTE` from the amounts. Only `type` changes; every amount is preserved. Marking a type that is already tax-only, or unmarking one that is not, is a no-op that returns the transaction unchanged. A type this cannot apply to, or a locked or already-filed transaction, answers `409`. Updating a transaction you do not own answers `404`, identical to one that does not exist. Category: Transactions Path parameters: transaction_id (string, required) - The unique identifier of the transaction to reclassify. Request body: taxOnly (boolean, required) - True to mark the transaction tax-only (a `SALE` becomes `TAX_COLLECTION`; a credit note becomes `TAX_REFUND`). False to unmark it, restoring `SALE` or re-deriving `FULL_CREDIT_NOTE` / `PARTIAL_CREDIT_NOTE`. Only `type` is affected; every amount is preserved. Response fields: id (string, required) - Kintsugi's unique identifier for the transaction. organizationId (string, required) - Organization the transaction belongs to. Present on every row because a portfolio-wide list spans organizations. externalId (string, required) - Your stable identifier for the transaction. externalFriendlyId (string) - Human-readable identifier from the source, such as an invoice number; an empty string when the source has only an `externalId`. date (string, required) - When the transaction occurred. This drives filing-period assignment. type (PublicTransactionTypeEnum, required) - Document shape of the transaction. Credit-note and tax-refund types reverse or adjust prior sales. allowed values: SALE, FULL_CREDIT_NOTE, PARTIAL_CREDIT_NOTE, TAX_REFUND, TAX_COLLECTION status (PublicTransactionStatusEnum, required) - Settlement state. Only `COMMITTED` counts toward filed liability; `PENDING` may still change. allowed values: PENDING, COMMITTED, CANCELLED, FULLY_REFUNDED, PARTIALLY_REFUNDED, INVALID [truncated, see the reference page] --- # List organization users GET /users Source: https://docs.trykintsugi.com/reference/2026-07-21/list-organization-users GET /users List organization users List the people attached to one organization: its members, plus anyone who has been invited and has not accepted yet (`status` `PENDING`). Rows are ordered by email. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`; omit `Organization-Id` when the bearer is an Owner or Admin of exactly one portfolio to list the partner firm team instead. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Category: Users Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (OrgUser[], required) - Users on this page, ordered by email. id (string, required) - Opaque unique identifier of the user. Treat as opaque; do not parse. For a `PENDING` row this is the invitation's identifier, which the remove endpoint accepts to revoke the invitation. organizationId (string, required) - Owning organization id (`orgn_…`), or the partner portfolio id (`part_…`) when the row is on the firm team. email (string, required) - User's email address. role (PublicUserRoleEnum, required) - Member's role in the organization, or null if the underlying role is not one of the published values. allowed values: OWNER, ADMIN, MEMBER status (PublicUserStatusEnum, required) - Membership status of the user in the organization. `INACTIVE` means the user cannot sign in and keeps their role until reactivated. `PENDING` means they have been invited and have not accepted yet, so they are not a member and have no name on file. allowed values: ACTIVE, INACTIVE, PENDING firstName (string, required) - User's first name. Empty string if unset. lastName (string, required) - User's last name. Empty string if unset. createdAt (string, required) - When the user account was created, or for a `PENDING` row when the invitation was sent. Null if unknown. nextCursor (string) - Opaque cursor for the next page, or null on the last page. Echo it as the request `cursor` to page forward. Pages are not a stable snapshot: if the roster changes while you walk it, a user can shift across a page boundary and be seen twice or missed. [truncated, see the reference page] --- # List pending organization invitations GET /users/invites Source: https://docs.trykintsugi.com/reference/2026-07-21/list-pending-organization-invitations GET /users/invites List pending organization invitations List the pending (not yet accepted) invitations for one organization. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`; omit it when the bearer is an Owner or Admin of exactly one portfolio to list firm invitations instead. Pass `limit` and the opaque `cursor` from a prior response's `nextCursor` to page forward; `hasMore` is false on the last page. Applies to organizations using Kintsugi-managed sign-in; an organization federated to its own identity provider manages invitations there. Category: Users Query parameters: limit (integer) - Maximum number of items to return. cursor (string) - Opaque cursor from a prior response's nextCursor or previousCursor. Omit for the first page. Response fields: items (OrgInvite[], required) - Pending invitations on this page. id (string, required) - Opaque unique identifier of the invitation. Treat as opaque; do not parse. Pass it to the revoke endpoint to cancel the invitation. organizationId (string, required) - Owning organization id (`orgn_…`), or the partner portfolio id (`part_…`) when the invitation is for the firm team. email (string, required) - Email address the invitation was sent to. role (PublicUserRoleEnum, required) - Role the invitee will hold once they accept, or null if the underlying role is not one of the published values. allowed values: OWNER, ADMIN, MEMBER status (PublicUserStatusEnum, required) - Always `PENDING`: the invitation has been sent but not yet accepted. allowed values: ACTIVE, INACTIVE, PENDING createdAt (string, required) - When the invitation was created, or null if unknown. expiresAt (string, required) - When the invitation expires, or null if unknown. nextCursor (string) - Opaque cursor for the next page, or null on the last page. Echo it as the request `cursor` to page forward. Pages are not a stable snapshot: if the pending invitations change while you walk them, one can shift across a page boundary and be seen twice or missed. previousCursor (string) - Always null: this list pages forward only over the provider's paging. hasMore (boolean) - Whether a next page exists. hasPrevious (boolean) - Always false: this list pages forward only. Response statuses: 200, 400, 401, 403, 404, 422, 503 --- # Invite a user to an organization POST /users/invites Source: https://docs.trykintsugi.com/reference/2026-07-21/invite-a-user-to-an-organization POST /users/invites Invite a user to an organization Invite a user to the organization by email. If the email already belongs to a Kintsugi user, they are added to the organization directly and the response `outcome` is `ADDED` with the new `user`; otherwise an invitation is sent and `outcome` is `INVITED` with the pending `invite`. Idempotent on the email: if they are already a member, or already have an invitation outstanding, the existing one is returned unchanged with a `200` instead of `201`, and their role is not modified. Use `PATCH /users/{userId}` to change a role. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. Only an Owner can assign the Owner role (403). Applies to organizations using Kintsugi-managed sign-in; an organization federated to its own identity provider manages invitations there. Category: Users Request body: email (string, required) - Email address of the user to invite or add to the organization. role (PublicUserRoleEnum, required) - Primary role to grant the user in the organization. allowed values: OWNER, ADMIN, MEMBER additionalRoles (string[]) - Optional additional role names to assign alongside the primary role. Response fields: outcome (PublicInviteOutcomeEnum, required) - `INVITED` when the result is an invitation, `ADDED` when an existing user holds membership directly. Branch on this rather than on which of `invite` / `user` is populated. Whether it was newly created is the response status: `201` created, `200` already existed. allowed values: INVITED, ADDED invite (OrgInvite, required) - The invitation when `outcome` is `INVITED`; null otherwise. id (string, required) - Opaque unique identifier of the invitation. Treat as opaque; do not parse. Pass it to the revoke endpoint to cancel the invitation. organizationId (string, required) - Owning organization id (`orgn_…`), or the partner portfolio id (`part_…`) when the invitation is for the firm team. email (string, required) - Email address the invitation was sent to. role (PublicUserRoleEnum, required) - Role the invitee will hold once they accept, or null if the underlying role is not one of the published values. allowed values: OWNER, ADMIN, MEMBER [truncated, see the reference page] --- # Revoke a pending organization invitation DELETE /users/invites/{invite_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/revoke-a-pending-organization-invitation DELETE /users/invites/{invite_id} Revoke a pending organization invitation Revoke a pending invitation by its opaque id. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. Returns 404 if the organization is not accessible or no such pending invitation exists; the response is empty on success. Applies to organizations using Kintsugi-managed sign-in; an organization federated to its own identity provider manages invitations there. Category: Users Path parameters: invite_id (string, required) - Opaque identifier of the invitation to revoke. Treat as opaque. Response statuses: 204, 400, 401, 403, 404, 422, 503 --- # Update an organization user's role PATCH /users/{user_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/update-an-organization-user-s-role PATCH /users/{user_id} Update an organization user's role Change a member's role in the organization (optionally replacing their additional roles). Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. You cannot change your own membership, only an Owner can change another Owner, and only an Owner can assign the Owner role; each returns 403. A `PENDING` user has no role to change and returns 409: revoke their invitation and send a new one. Returns 404 if the organization is not accessible; the response is empty on success. Category: Users Path parameters: user_id (string, required) - Opaque identifier of the user to update. Treat as opaque. Request body: role (PublicUserRoleEnum, required) - New primary role for the user in the organization. allowed values: OWNER, ADMIN, MEMBER additionalRoles (string[]) - Optional additional role names to assign alongside the primary role. When provided, replaces the user's current additional roles; omit the field to leave them unchanged, or send an empty list to clear them. Response statuses: 204, 400, 401, 403, 404, 409, 422, 503 --- # Remove a user from an organization DELETE /users/{user_id} Source: https://docs.trykintsugi.com/reference/2026-07-21/remove-a-user-from-an-organization DELETE /users/{user_id} Remove a user from an organization Remove a member from the organization. If the id is a `PENDING` user, their invitation is revoked instead. Requires a user credential (an API key is rejected) that is an Owner or Admin of the organization. Select a client organization with `Organization-Id`, or omit it for the partner firm team. You cannot remove yourself, and only an Owner can remove another Owner; either returns 403. Returns 404 if the organization is not accessible, or no such user or invitation exists; the response is empty on success. Category: Users Path parameters: user_id (string, required) - Opaque identifier of the user to remove. Treat as opaque. Response statuses: 204, 400, 401, 403, 404, 422, 503