Calculate Taxes Owed for a Specific User

1: Create a User

To create a new User call the POST /users API endpoint. You can also follow the Getting Started guide to create a User. Ensure you have the resulting userId available for the next step.

2: Create Incomes and Expense Deductions for Your User

There are multiple ways to include incomes and expenses for a Tax Calculation. By default, Abound® will use the sum of the incomes and expenses created using the POST /users/{userId}/incomes and POST /users/{userId}/expenses to generate the 1099Income and expenseDeduction values in our tax calculator. However, you can manually include the 1099income and expenseDeduction values when calculating taxes.

For a more in-depth guide of adding incomes an deductions to a tax calculation view the following guides:

3: Calculate Taxes Owed

When calculating taxes using the PUT /users/{userId}/taxes/{year} API endpoint, we recommend updating the filingStatus and filingState for your user. Updating the filingStatus affects how your user's income is applied to specific tax brackets and updating the filingState will affect the stateIncomeTax value.

📘

If you do not set a filingState when calculating taxes, the API will default the filingState to CA.

curl \
  --request PUT \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2022 \
  --header 'Authorization: Bearer <<apiKey>>' \
  --header 'Content-Type: application/json' \
  --data '{
    "taxes": {
      "filingState": "CA",
      "filingStatus": "single"
    }
  }'
const { default: Abound, Environment } = require("@withabound/node-sdk");

const abound = new Abound({
  appId: "<<sandbox_app_id>>",
  appSecret: "<<sandbox_app_secret>>",
  environment: Environment.SANDBOX,
  apiVersion: "v2",
});

(async () => {
  const response = await abound.taxes.calculate(
    "<<testUserId>>",
    "2022",
    {
      filingState: "CA",
      filingStatus: "single",
    }
  );
  
  console.log(response);
})();
import requests

url = "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2022"

payload = {"taxes": {
        "filingState": "CA",
        "filingStatus": "single"
    }}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "Authorization": "Bearer <<apiKey>>"
}

response = requests.request("PUT", url, json=payload, headers=headers)

print(response.text)
//import com.withabound.AboundConfig;
//import com.withabound.models.*;
//import com.withabound.resources.base*;

AboundConfig aboundConfig = new AboundConfig(
  "<<sandbox_app_id>>",
  "<<sandbox_app_secret>>",
  AboundEnvironment.SANDBOX,
  AboundApiVersion.V2
);
Abound abound = new Abound(aboundConfig);

String userId = "<<testUserId>>";
String year = "2022";
TaxRequest taxUpdates = TaxRequest.builder()
  .filingState("CA")
  .filingStatus("single"
  .build();

AboundResponse<Tax> response = abound.taxes().calculate(userId, year, taxUpdates);

System.out.println(response.getData().getEffectiveTaxRate());
package main

import (
    "bytes"
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2022"

    var requestBody = []byte(`{
        "taxes": {
            "filingState": "CA",
            "filingStatus": "single"
        }
    }`)

    req, _ := http.NewRequest("PUT", url, bytes.NewBuffer(requestBody))

    req.Header.Add("Accept", "application/json")
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Authorization", "Bearer <<apiKey>>")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
// using RestSharp;

var client = new RestClient("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2022");
var request = new RestRequest(Method.PUT);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer <<apiKey>>");
request.AddJsonBody(new {
  taxes = new {
    filingState = "CA",
    filingStatus = "single"
  }
});
IRestResponse response = client.Execute(request);
require 'uri'
require 'net/http'
require 'openssl'
require 'json'

url = URI("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2022")
requestBody = {
  taxes: {
    filingState: 'CA',
    filingStatus: 'single'
  }
}

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["Accept"] = 'application/json'
request["Content-Type"] = 'application/json'
request["Authorization"] = 'Bearer <<apiKey>>'
request.body = requestBody.to_json

response = http.request(request)
puts response.read_body
FieldDescription
filingStateThe state in which the user earns their 1099 income (this is typically the state they live in). This value is used to calculate the user's stateIncomeTax.
filingStatusThe user's filing status, which determines the tax bracket to use for tax calculations. The possible values are single, married, marriedSeparately, and headOfHousehold.
{
  "data": {
    "1099Income": 85329.67,
    "effectiveTaxRate": 0.3203,
    "expenseDeduction": 15321.99,
    "federalIncomeTax": 11556.64,
    "federalTaxOutstanding": 21305.31,
    "federalTaxTotal": 21305.31,
    "filingState": "CA",
    "filingStatus": "single",
    "irsPayments": 0,
    "quarterlyPayments": 0,
    "marginalTaxRate": 0.4472,
    "medicareTax": 1847.79,
    "mileage": 1761.4,
    "mileageDeduction": 1012.8,
    "otherIrsPayments": 0,
    "otherStatePayments": 0,
    "otherTaxWithholdings": 0,
    "qbiDeduction": 12824.11,
    "selfEmploymentTax": 9748.67,
    "smartTaxRate": 0.3838,
    "socialSecurityTax": 7900.88,
    "stateIncomeTax": 6026.71,
    "stateTaxTotal": 6026.71,
    "taxBalance": 27332.02,
    "taxWithholdings": 0,
    "taxWithholdingsPending": 0,
    "totalTax": 27332.02,
    "w2Income": 60000,
    "year": "2022"
  }
}

When submitting Federal Quarterly Tax Payments to Abound®, the value to set as the amount is the federalTaxOutstanding. This value represents the remaining tax balance after payments previously made to the IRS. For the taxes object example above, the amount for the user’s Quarterly Tax Payment to the IRS would be 21305.31.

4: Calculate Taxes Owed for A Specific Year

To calculate taxes for prior years for your User change the {year} argument in the GET /users/{userId}/taxes/{year} API endpoint.

curl \
  --request GET \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020 \
  --header 'Authorization: Bearer <<apiKey>>'
const { default: Abound, Environment } = require("@withabound/node-sdk");

const abound = new Abound({
  appId: "<<sandbox_app_id>>",
  appSecret: "<<sandbox_app_secret>>",
  environment: Environment.SANDBOX,
  apiVersion: "v2",
});

(async () => {
  const response = await abound.taxes.retrieve(
    "<<testUserId>>",
    "2020"
  );
  
  console.log(response);
})();
import requests

url = "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020"

headers = {
    "Accept": "application/json",
    "Authorization": "Bearer <<apiKey>>"
}

response = requests.request("GET", url, headers=headers)

print(response.text)
//import com.withabound.AboundConfig;
//import com.withabound.models.*;
//import com.withabound.resources.base*;

AboundConfig aboundConfig = new AboundConfig(
  "<<sandbox_app_id>>",
  "<<sandbox_app_secret>>",
  AboundEnvironment.SANDBOX,
  AboundApiVersion.V2
);

String userId = "<<testUserId>>";
String year = "2020";

AboundResponse<Tax> response = abound.taxes().retrieve(userId, year);

System.out.println(response.getData().getTotalTax());
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")
    req.Header.Add("Authorization", "Bearer <<apiKey>>")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
// using RestSharp;

var client = new RestClient("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer <<apiKey>>");
IRestResponse response = client.Execute(request);
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'
request["Authorization"] = 'Bearer <<apiKey>>'

response = http.request(request)
puts response.read_body

At any time you can retrieve the user's year-to-date (YTD) tax information for a particular year. This information will always be the most up-to-date tax information for your user.