Documentation Index
Fetch the complete documentation index at: https://docs.commenda.io/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Commenda’s exposure engine evaluates your transaction data against registration threshold rules for jurisdictions worldwide. It determines whether your business has exceeded — or is approaching — the point where you must register to collect and remit indirect tax in a given jurisdiction.
The exposure engine supports:
- US economic thresholds — state-level sales and transaction count thresholds (post-Wayfair)
- Canada GST/HST — federal and provincial thresholds
- UK VAT — standard UK VAT registration threshold
- EU country-level VAT — per-country thresholds for EU member states
- EU trade bloc rules — Union OSS, Non-Union OSS, and IOSS schemes with cross-border scope
Key concepts
Exposure rules
Each jurisdiction has one or more exposure rules that define when registration is required. A rule specifies:
| Field | Description |
|---|
exposure_rule_id | Unique identifier for the rule |
exposure_type | The type of tax obligation (EXPOSURE, EXPOSURE_ECONOMIC, or EXPOSURE_PHYSICAL) |
threshold_type | Whether the threshold is based on SALES_ONLY, SALES_OR_TRANSACTIONS, or SALES_AND_TRANSACTIONS |
sales_threshold | Revenue amount that triggers registration |
transactions_threshold | Transaction count that triggers registration |
evaluation_period_type | Time window for measuring activity (e.g., PRECEDING_12_MONTHS, PREVIOUS_OR_CURRENT_CALENDAR_YEAR) |
location_based_scope | Which transactions count toward the threshold (DESTINATION, WORLDWIDE, INTRA_COMMUNITY, or IMPORT) |
exclusion_types | Transaction types excluded from threshold calculations (e.g., marketplace, B2B, resale) |
establishment_types | Business establishment types that determine which rule variant applies |
max_transaction_value | Maximum per-transaction value for inclusion (e.g., €150 for IOSS) |
Multi-rule jurisdictions
Some jurisdictions have multiple rules that apply based on your business’s establishment status. For example, an EU member state may have:
- A resident rule for businesses with a physical establishment in that country (e.g., office, warehouse)
- A non-resident rule for businesses selling into the country without a local establishment
The engine automatically selects the applicable rules based on your registered locations.
Location-based scope
Rules define which transactions count toward the threshold based on the geographic relationship between buyer and seller:
| Scope | Description |
|---|
DESTINATION | Transactions where the buyer is in the rule’s jurisdiction |
WORLDWIDE | All transactions regardless of destination |
INTRA_COMMUNITY | Cross-border transactions within a trade bloc (e.g., EU seller to EU buyer in a different member state) |
IMPORT | Transactions where the seller is outside the trade bloc and the buyer is inside |
Exclusions
Certain transactions are automatically excluded from threshold calculations when the rule defines exclusions:
- Marketplace transactions — sales facilitated by a marketplace that collects tax on your behalf
- B2B transactions — sales to business customers identified by a business identification number (e.g., VAT number), which are typically subject to reverse charge
- Resale transactions — sales to customers with valid resale certificates
- Product taxability — specific product categories excluded per jurisdiction rules (e.g., tangible goods excluded from digital services thresholds)
- Destination registered — transactions to jurisdictions where you are already registered
Max transaction value (IOSS)
The EU Import One-Stop Shop (IOSS) scheme applies only to consignments valued at or below €150. Transactions exceeding this cap are excluded from IOSS threshold tracking. An invoice exactly equal to the cap is included.
Querying exposure data
Use the registration thresholds endpoint with v2=true to retrieve exposure data across all supported jurisdictions:
curl -X GET "https://transaction-tax.api.in.commenda.io/api/v1/nexus?corporation_id={corporation_id}&v2=true" \
-H "Authorization: Bearer <your_token>"
Response structure
The v2 response returns an array of jurisdiction objects, each representing one exposure rule evaluation:
{
"data": {
"corporation_id": "74df772f-9260-42cf-9c20-3b613b60fecd",
"jurisdictions": [
{
"jurisdiction_id": "STATE_US_NY_1036",
"jurisdiction_type": "STATE",
"jurisdiction_name": "New York",
"exposure_type": "EXPOSURE_ECONOMIC",
"exposure_rule_id": "us_ny_economic",
"subdivision": "NY",
"currency": "USD",
"rule": {
"sales_threshold": 500000,
"transactions_threshold": null,
"threshold_type": "SALES_ONLY",
"evaluation_period_type": "PREVIOUS_OR_CURRENT_CALENDAR_YEAR",
"location_based_scope": "DESTINATION",
"exclusion_types": ["TRANSACTION.MARKETPLACE"],
"establishment_types": []
},
"calculation": {
"included_sales": 320000,
"included_transactions": 1500,
"gross_sales": 350000,
"gross_transactions": 1800,
"sales_exposure_percentage": 0.64,
"transactions_exposure_percentage": 0
},
"is_nexus_breached": false,
"recommended_registration_content_ids": ["REG_STATE_CEN_36"]
},
{
"jurisdiction_id": "TRADEBLOC_EU_3000",
"jurisdiction_type": "TRADEBLOC",
"jurisdiction_name": "EU Union OSS",
"exposure_type": "EXPOSURE",
"exposure_rule_id": "eu_union_oss",
"subdivision": "",
"currency": "EUR",
"rule": {
"sales_threshold": 10000,
"transactions_threshold": null,
"threshold_type": "SALES_ONLY",
"evaluation_period_type": "PREVIOUS_OR_CURRENT_CALENDAR_YEAR",
"location_based_scope": "INTRA_COMMUNITY",
"exclusion_types": ["CUSTOMER.B2B"],
"establishment_types": [],
"max_transaction_value": 150
},
"calculation": {
"included_sales": 8500,
"included_transactions": 42,
"gross_sales": 12000,
"gross_transactions": 60,
"sales_exposure_percentage": 0.85,
"transactions_exposure_percentage": 0
},
"is_nexus_breached": false,
"recommended_registration_content_ids": ["REG_TRADEBLOC_EU_3000_UOSS"]
}
]
},
"message": "Successfully fetched nexus."
}
Response fields
Each jurisdiction object includes:
| Field | Description |
|---|
jurisdiction_id | Internal identifier for the jurisdiction. For trade bloc rules, this is the trade bloc ID (e.g., TRADEBLOC_EU_3000) |
jurisdiction_type | STATE, STATE_OR_PROVINCE, COUNTRY, or TRADEBLOC |
jurisdiction_name | Human-readable name of the jurisdiction (e.g., “New York”, “United Kingdom”, “EU Union OSS”) |
exposure_type | Type of exposure obligation: EXPOSURE, EXPOSURE_ECONOMIC, or EXPOSURE_PHYSICAL |
exposure_rule_id | Identifier for the specific rule being evaluated |
subdivision | State or province code, if applicable |
currency | Currency of the threshold amounts |
rule | The threshold rule being applied (see Exposure rules for field details) |
calculation | Your current progress toward the threshold |
is_nexus_breached | Whether you have exceeded the registration threshold |
date_of_breach | Date when the threshold was exceeded, if breached |
recommended_registration_content_ids | An array of V2 registration content IDs recommended for this jurisdiction (e.g., ["REG_STATE_CEN_06"]). Use these with the V2 Registration API to create a registration. |
A single jurisdiction may appear multiple times in the response if multiple exposure rules apply (e.g., separate rules for goods and services in France or Ireland).
Calculation fields
| Field | Description |
|---|
included_sales | Revenue counted toward the threshold after applying exclusions |
included_transactions | Transaction count after exclusions |
gross_sales | Total revenue before exclusions |
gross_transactions | Total transaction count before exclusions |
sales_exposure_percentage | Ratio of included sales to the sales threshold (0 to 1+) |
transactions_exposure_percentage | Ratio of included transactions to the transactions threshold (0 to 1+) |
Triggering a sync
The exposure engine runs automatically on a daily schedule and lazily on read. You can also trigger an on-demand recompute for a specific corporation via the public Sync exposure endpoint:
curl -X POST "https://transaction-tax.api.in.commenda.io/api/v1/exposure/sync?corporation_id={corporation_id}" \
-H "Authorization: Bearer <your_token>"
Every successful run emits an INDIRECT_TAX.EXPOSURE.COMPUTED webhook with the corporation’s full current set of exposed jurisdictions, so any subscribers stay in sync without polling.
Physical presence
If your business has a physical establishment (office, warehouse, or other location) in a jurisdiction, the engine evaluates resident rules for that jurisdiction. Resident rules may have different thresholds or no threshold at all — physical presence can trigger an immediate registration obligation.
Register your business locations via the Locations API to ensure the engine correctly identifies which rules apply.