[TIPS] Speeding Up Invoice Tax Calculations with ONESOURCE REST API: Pros and Cons
By JoeVu, at: Nov. 11, 2024, 3:55 p.m.
Speeding Up Invoice Tax Calculations with ONESOURCE REST API: Pros and Cons
For companies processing high invoice volumes, the ONESOURCE REST API offers a clear advantage over SOAP. With the ability to handle up to 1,000 invoices in a single call, the REST API can significantly reduce processing time and server load compared to the SOAP API, which only processes one invoice per request.
A sample Python code for OneSource REST Client is below, or you can click on the link here
import requests
import uuid
class OnesourceRestClient:
BASE_URL = "https://api-uat.onesourcetax.com" # default is the uat url
TOKEN_URL = f"{BASE_URL}/oauth2/v1/token"
TAX_URL = f"{BASE_URL}/indirect-tax-determination/taxes/v1/calculate"
DEFAULT_CONFIG = {
"base_url": "https://api-uat.onesourcetax.com",
"company_role": "S",
"calling_source": "DM",
"charge_response": "CombineWithLine",
"response_summary": "FullDetails",
"external_company_id": "GLINTECO",
"document_amount_type": "GrossPlusTaxAmount",
"calling_system_number": "DM",
"charge_included_in_amounts": "false",
}
SCOPE = "urn:tr:onesource:auth:api:IndirectTaxDetermination" # fixed scope for tax determination
def __init__(self, transaction_data, consumer_key, consumer_secret):
self.transaction_data = transaction_data
self.consumer_key = consumer_key
self.consumer_secret = consumer_secret
self.config = self.DEFAULT_CONFIG
def make_request(
self, method, url, headers=None, params=None, payload=None
):
headers = headers or {
"Content-Type": "application/json",
}
response = requests.request(
method=method, url=url, headers=headers, json=payload
)
return response
def make_post_request(self, url, headers=None, payload=None):
return self.make_request("post", url, headers=headers, payload=payload)
def fetch_access_token(self) -> str:
headers = {
"ClientAssertion": f"Bearer {self.consumer_key}",
"Content-Type": "application/json",
"Correlation-Id": str(uuid.uuid4()),
}
payload = {
"grant_type": "client_credentials",
"client_id": self.consumer_key,
"client_secret": self.consumer_secret,
"scopes": self.SCOPE,
}
print(
f"Fetching access token from ONESOURCE Rest. Payload: {payload}, Headers: {headers}"
)
response = self.make_post_request(
self.TOKEN_URL, headers=headers, payload=payload
)
self.access_token = response.json().get("access_token")
print(f"New access token fetched: {self.access_token}")
return self.access_token
def fetch_tax(self) -> None:
print("Fetching tax from ONESOURCE Rest")
self.fetch_access_token()
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/vnd.tri.onesource.idt+json",
"Correlation-Id": str(uuid.uuid4()),
}
response = self.make_post_request(
self.TAX_URL, headers=headers, payload=self.transaction_data
)
self.response_data = response.json()
print(f"Tax fetched: {self.response_data}")
return self.response_data
and here is how to use this
data = "<your transaction_data>"
consumer_key = "<your consumer_key>"
consumer_secret = "<your consumer_secret>"
client = OnesourceRestClient(data, consumer_key, consumer_secret)
client.fetch_tax()
Key Advantages
- Batch Processing: Submit up to 1,000 invoices per call, saving time and reducing server load.
- Enhanced Performance: Fewer requests mean faster responses and streamlined workflows.
- Efficient Rate Limits: With a rate limit of 300 requests, ONESOURCE REST API ensures stable, high-throughput processing, with each request accommodating a significant number of invoices.
{
"Content-Type": "application/json",
"Content-Length": "253",
"Connection": "keep-alive",
"Date": "Wed, 13 Nov 2024 14:59:45 GMT",
"Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS, HEAD",
...
"X-RATELIMIT-ALLOWED": "300",
"X-RATELIMIT-USED": "1",
"X-RATELIMIT-AVAILABLE": "299",
"X-RATELIMIT-EXPIRY": "1731510000000",
"Cache-Control": "no-cache, no-store, must-revalidate",
"Expires": "-1",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "",
"Access-Control-Max-Age": "3628800",
"X-Cache": "Miss from cloudfront",
"X-Amz-Cf-Pop": "SIN2-P3",
}
A Potential Drawback
However, there’s one downside: Error Handling. If one invoice in the batch of 1,000 encounters an issue, the entire request may fail. This can lead to delays and the need for smaller batch sizes to ensure accuracy.
More information can be found here
Tips for Optimizing Batch Processing
- Run Smaller Batches: Consider grouping invoices in batches of 100-200 to minimize risk while still enjoying speed improvements.
- Error Monitoring: Implement robust error handling and logging to quickly identify and resolve issues within batches.
- Testing and Validation: Test batch sizes to find the optimal point where you gain efficiency but minimize the risk of failed requests.
- Monitor Rate Limits: Keep an eye on the rate limit headers (
X-RATELIMIT-ALLOWED
,X-RATELIMIT-USED
, andX-RATELIMIT-AVAILABLE
) to avoid hitting limits and plan usage accordingly.
While the ONESOURCE REST API is powerful, thoughtful implementation—like managing batch sizes—ensures you get the best of its benefits without being slowed down by batch failures.
For more on tax API optimization, visit Glinteco.
Sample ONESOURCE REST BATCH payload data: here
Sample ONESOURCE REST BATCH response data: here