Skip to main content

API Changelog

Version 2026-03-01

Release Date: March 1, 2026This version adds IP-based tax resolution to calculations and platform calculations, enabling tax determination from a customer’s IP address without requiring a full street address.

New Feature: IP-Based Tax Resolution

IP Resolution

Pass a customer IP address instead of a full address for tax calculations.
  • Works with both /tax/calculations and /tax/platform/calculations
  • Supports IPv4 and IPv6 addresses

Resolution Modes

Control how insufficient IP data is handled.
  • strict - Error if insufficient detail
  • zero - Return zero-rate
  • approximate - Use most populous ZIP
  • best_effort - Try approximate, fall back to zero

The customer.ip Object

Instead of providing customer.address, you can now pass customer.ip:
{
  "customer": {
    "type": "CONSUMER",
    "ip": {
      "value": "217.217.113.167",
      "resolution": "strict"
    }
  }
}
FieldTypeRequiredDescription
valuestringYesA valid IPv4 or IPv6 address
resolutionstringNoResolution strategy (default: "strict")
At least one of customer.address or customer.ip must be provided. You can also provide both — the address will be used first, with IP as a fallback.

Resolution Modes

ModeBehavior
strict (default)Returns an error if IP cannot resolve to sufficient detail for tax calculation
zeroReturns a zero-rate response immediately if resolution is insufficient
approximateAttempts to resolve the IP to an address using heuristics
best_effortTries approximate first, falls back to zero rates if that also fails
Numeral strongly recommends using strict mode to stay as compliant as possible.

New Response Fields

Calculation responses now include these additional fields:
FieldTypeDescription
location_sourcestring"address" or "ip" — which input was used for tax determination
resolution_precisionstringPrecision level: STREET, POSTAL_PLUS, POSTAL, PROVINCE, COUNTRY, or APPROXIMATED
address_usedobjectThe resolved address that was actually used for tax calculation

Example: IP-Based Calculation

curl -X POST https://api.numeralhq.com/tax/calculations \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "X-API-Version: 2026-03-01" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "type": "CONSUMER",
      "ip": {
        "value": "217.217.113.167",
        "resolution": "strict"
      }
    },
    "order_details": {
      "customer_currency_code": "USD",
      "tax_included_in_amount": false,
      "automatic_tax": "auto",
      "line_items": [
        {
          "product_category": "SAAS_GENERAL",
          "reference_line_item_id": "ip-test-001",
          "amount": 10000,
          "quantity": 1
        }
      ]
    }
  }'
Response:
{
  "testmode": true,
  "id": "calc_...",
  "object": "tax.calculation",
  "customer_currency_code": "USD",
  "line_items": [
    {
      "line_item_id": "li_...",
      "product": {
        "reference_line_item_id": "ip-test-001",
        "reference_product_id": "default-saas-general",
        "reference_product_name": "Default SAAS_GENERAL Product",
        "product_tax_code": "SAAS_GENERAL"
      },
      "tax_jurisdictions": [
        {
          "tax_rate": 0.06,
          "tax_due_decimal": 600,
          "fee_amount": 0,
          "rate_type": "GENERAL STATE SALES TAX",
          "tax_authority_name": "Pennsylvania",
          "tax_type": "SALES"
        },
        {
          "tax_rate": 0.01,
          "tax_due_decimal": 100,
          "fee_amount": 0,
          "rate_type": "GENERAL COUNTY LOCAL SALES TAX",
          "tax_authority_name": "ALLEGHENY",
          "tax_type": "SALES"
        }
      ],
      "tax_amount": 700,
      "amount_excluding_tax": 10000,
      "amount_including_tax": 10700,
      "quantity": 1
    }
  ],
  "total_tax_amount": 700,
  "tax_included_in_amount": false,
  "total_amount_excluding_tax": 10000,
  "total_amount_including_tax": 10700,
  "expires_at": 1771710514,
  "customer": { "type": "CONSUMER" },
  "automatic_tax": "auto",
  "address_resolution_status": "POSTAL_ONLY",
  "address_used": {
    "address_line_1": "",
    "address_line_2": "",
    "address_city": "",
    "address_province": "PA",
    "address_postal_code": "15212",
    "address_country": "US"
  },
  "location_source": "ip",
  "resolution_precision": "POSTAL"
}

New Error Types

TypeHTTP CodeDescription
INVALID_IP_FORMAT400ip.value is not a valid IPv4 or IPv6 address
IP_RESOLUTION_FAILED422IP could not be resolved to any country
IP_RESOLUTION_INSUFFICIENT_US422IP resolved to a US state but no postal code was found
IP_RESOLUTION_INSUFFICIENT_CA422IP resolved to CA but no province was found

Error Codes Reference

See the complete list of error types and their meanings.

Migration Guide

From 2026-01-01 to 2026-03-01

There are no breaking changes from 2026-01-01. All existing requests continue to work as-is.
  1. Update your X-API-Version header to 2026-03-01
  2. Optionally use customer.ip instead of or in addition to customer.address
  3. Handle new 422 error types if using IP resolution with strict mode
  4. Check location_source in responses to see whether address or IP was used

Version 2026-01-01

Release Date: January 1, 2026This version introduces Merchant Management and Platform Calculations for marketplace and payment processor scenarios.

New Endpoints

Merchant CRUD

Full create, read, update, and delete operations for merchants (sellers) on your platform.
  • POST /tax/merchants - Create merchant
  • GET /tax/merchants - List merchants
  • GET /tax/merchants/:id - Get merchant
  • POST /tax/merchants/:id - Update merchant
  • DELETE /tax/merchants/:id - Delete merchant

Platform Calculations

Tax calculations for marketplace transactions with merchant context.
  • POST /tax/platform/calculations

Platform Transactions

Convert platform calculations into recorded transactions for tax reporting.
  • POST /tax/platform/transactions

Breaking Changes

Amount is Per-Unit in Platform CalculationsThe most significant change in this version is how amount is interpreted in the /platform/calculations endpoint.
EndpointAmount Behavior
/tax/calculationsTotal line item value
/tax/platform/calculationsPer-unit price
Example:
// For 3 items at $25.00 each

// Standard calculations (amount = total)
{
  "amount": 7500,  // $75.00 total
  "quantity": 3
}

// Platform calculations (amount = per-unit)
{
  "amount": 2500,  // $25.00 per unit
  "quantity": 3    // taxable base = $75.00
}

New Features

Merchant Management

Create and manage merchants (sellers) on your platform:
curl -X POST https://api.numeralhq.com/tax/merchants \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "X-API-Version: 2026-01-01" \
  -H "Content-Type: application/json" \
  -d '{
    "reference_merchant_id": "seller-123",
    "name": "Acme Seller",
    "default_address": {
      "address_line_1": "123 Main St",
      "address_city": "San Francisco",
      "address_province": "CA",
      "address_postal_code": "94105",
      "address_country": "US"
    }
  }'
Key features:
  • Use your own IDs via reference_merchant_id
  • Store merchant tax IDs for B2B transactions
  • Default addresses used as origin in calculations
  • Testmode isolation (test merchants separate from live)

Platform Calculations

Calculate taxes for marketplace/platform transactions:
curl -X POST https://api.numeralhq.com/tax/platform/calculations \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "X-API-Version: 2026-01-01" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "address": { ... }
    },
    "merchant": {
      "merchant_id": "seller-123"
    },
    "order_details": {
      "customer_currency_code": "USD",
      "tax_included_in_amount": false,
      "line_items": [
        { "amount": 2500, "quantity": 3, "product_category": "GENERAL_MERCHANDISE" }
      ]
    },
    "roles": ["marketplace_provider"]
  }'
Key features:
  • Per-unit pricing - amount × quantity = taxable base
  • Merchant context - Link calculations to specific sellers
  • Platform roles - Specify your role (marketplace, payment processor, merchant of record)
  • Fee calculations - Separate tax calculation for platform fees
  • Enhanced response - Includes tax_authority_name, tax_authority_type, tax_type

Platform Roles

Specify your role in the transaction:
RoleDescription
marketplace_providerYou operate a marketplace connecting buyers and sellers
payment_processorYou process payments for the transaction
merchant_of_recordYou are the legal seller of record

Platform Transactions

Convert platform calculations into recorded transactions for tax reporting and filing:
curl -X POST https://api.numeralhq.com/tax/platform/transactions \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "X-API-Version: 2026-01-01" \
  -H "Content-Type: application/json" \
  -d '{
    "platform_calculation_id": "plat_calc_abc123",
    "reference_order_id": "order_12345",
    "reference_payment_id": "pay_67890",
    "transaction_processed_at": 1736300000
  }'
Key features:
  • Returns a list - May return one or two transactions depending on your platform role
  • Payment processors - Receive separate order and fee transactions
  • Marketplace providers / Merchants of record - Receive a single order transaction
  • Transaction types - type: "order" for sales, type: "fee" for platform fees
Platform RoleTransactions Created
payment_processor2 (order + fee)
marketplace_provider1 (order only)
merchant_of_record1 (order only)

Fee Calculations

Calculate taxes on platform fees separately from order items:
{
  "order_details": { ... },
  "fee_details": {
    "line_items": [
      { "amount": 299, "quantity": 1, "product_category": "ELECTRONIC_GOODS" }
    ]
  }
}
The response includes separate totals:
{
  "totals": {
    "order": { "tax_amount": 875 },
    "fees": { "tax_amount": 26 }
  }
}

Enhanced Tax Response

Platform calculations include additional jurisdiction details:
{
  "tax_jurisdictions": [
    {
      "tax_rate": 0.0875,
      "rate_type": "SALES TAX",
      "jurisdiction_name": "California",
      "tax_authority_name": "California State",
      "tax_authority_type": "STATE",
      "tax_type": "SALES"
    }
  ]
}
FieldDescription
tax_authority_nameHuman-readable authority name
tax_authority_typeSTATE, COUNTY, CITY, or DISTRICT
tax_typeSALES, USE, VAT, or GST

New Error Format

Breaking Change: Simplified Error ResponseError responses now use a flattened structure instead of the nested error object from previous versions.
Previous format (2025-05-12 and earlier):
{
  "error": {
    "code": "product_not_found",
    "message": "Product not found"
  }
}
New format (2026-01-01+):
{
  "code": 400,
  "type": "PRODUCT_NOT_FOUND",
  "message": "Product not found"
}
Key changes:
  • Flattened structure - No more nested error object
  • HTTP status in response - code field contains the HTTP status code
  • Uppercase error types - Error types are now SCREAMING_SNAKE_CASE
  • Consistent typing - Use the type field for programmatic error handling

Error Codes Reference

See the complete list of error types and their meanings.

Previous Versions

VersionKey Features
2026-01-01Merchant management, platform calculations, per-unit pricing, fee calculations
2025-05-12Customer types (B2B/B2C), tax IDs, 32 currencies, automatic_tax
2024-09-01Base version with core tax calculation features