Keep User's Taxes Up to Date

There are several ways to adjust your user's tax liability:

  • Filing state & filing status
  • New 1099 income
  • Business expenses deductions
  • Business mileage
  • W-2 income

It's important to note that none of these adjustments are required, however, their incorporation will increase the accuracy of your user's tax calculation.

Adjusting for Filing State and Filing Status

Updating the filingStatus affects how your user's income is applied to specific tax brackets, while updating the filingState will affect the stateIncomeTax value. Both values can be updated by calling the PUT /users/{userId}/taxes/{year} API endpoint.

curl \
  --request PUT \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020 \
  --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>>",
    "2020",
    {
      filingState: "ca",
      filingStatus: "single",
    }
  );
  
  console.log(response);
})();
import requests

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

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.squareup.okhttp.*;
// import com.google.gson.JsonObject;

OkHttpClient client = new OkHttpClient();

JsonObject requestBody = new JsonObject();
JsonObject taxes = new JsonObject();

taxes.addProperty("filingState", "ca");
taxes.addProperty("filingStatus", "single");

requestBody.add("taxes", taxes);

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, requestBody.toString());
Request request = new Request.Builder()
  .url("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020")
  .put(body)
  .addHeader("Accept", "application/json")
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer <<apiKey>>")
  .build();

Response response = client.newCall(request).execute();
package main

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

func main() {

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

    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/2020");
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/2020")
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

Field

Description

filingState

The 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.
The value should be the lowercase abbreviation of the state ("ca" for California).

filingStatus

The user's filing status, which determines the tax bracket to use for tax calculations. The possible values are single, married, marriedSeparately, and headOfHousehold.

The response from this API call will be the same as detailed in the Retrieve Your User's YTD Taxes Guide.

Adjusting for New 1099 Income

You should update your user's YTD running total of 1099 income as soon as new 1099 income is detected on your platform. This can be accomplished in two ways:

  1. Utilize the POST /users/{userId}/incomes API endpoint. All 1099 incomes for a year will be summed up and included in the tax calculation.
  2. Update the 1099Income value by manually by calling the PUT/users/{userId}/taxes/{year} API endpoint.

If you're looking to find the tax liability on specific 1099 incomes (i.e. a paycheck, paid invoice, collection of incomes, etc.) read the guide: Taxes on Specific Incomes.

curl \
  --request PUT \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020 \
  --header 'Authorization: Bearer <<apiKey>>' \
  --header 'Content-Type: application/json' \
  --data '{
    "taxes": {
      "1099Income": 85329.67
    }
  }'
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>>",
    "2020",
    {
      "1099Income": 85329.67,
    }
  );
  
  console.log(response);
})();
import requests

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

payload = {"taxes": {"1099Income": 85329.67}}
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.squareup.okhttp.*;
// import com.google.gson.JsonObject;

OkHttpClient client = new OkHttpClient();

JsonObject requestBody = new JsonObject();
JsonObject taxes = new JsonObject();

taxes.addProperty("1099Income", 85329.67);

requestBody.add("taxes", taxes);

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, requestBody.toString());
Request request = new Request.Builder()
  .url("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020")
  .put(body)
  .addHeader("Accept", "application/json")
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer <<apiKey>>")
  .build();

Response response = client.newCall(request).execute();
package main

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

func main() {

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

    var requestBody = []byte(`{
        "taxes": {
            "1099Income": 85329.67
        }
    }`)

    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/2020");
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 {
    1099Income = 85329.67
  }
});
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/2020")
requestBody = {
  taxes: {
    '1099Income': 85329.67
  }
}

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

Field

Description

1099Income

The total annual 1099 income for the user. The tax totals returned are the taxes owed on this income.

The response from this API call is the same as detailed in the Retrieve User's YTD Taxes guide.

Adjusting for Business Expenses Deductions

Similar to the incomes explained above, there are two ways to keep the business expenses (and thus the tax calculations) of your UserUser - A single end-user of your application. Each user has a unique userId, which should be stored in your database and used to make API requests on behalf of this individual. in sync with Abound:

  1. Utilize the POST /users/{userId}/expenses API endpoint. The deduction value of all expenses for a given year will be summed up and applied to the expenseDeduction for tax calculations.
  2. You can call the PUT /users/{userId}/taxes/{year} API endpoint and pass a custom numerical value for the expenseDeduction field, as shown below.
curl \
  --request PUT \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020 \
  --header 'Authorization: Bearer <<apiKey>>' \
  --header 'Content-Type: application/json' \
  --data '{
    "taxes": {
      "expenseDeduction": 15321.99
    }
  }'
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>>",
    "2020",
    {
      expenseDeduction: 15321.99,
    }
  );
  
  console.log(response);
})();
import requests

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

payload = {"taxes": {"expenseDeduction": 15321.99}}
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.squareup.okhttp.*;
// import com.google.gson.JsonObject;

OkHttpClient client = new OkHttpClient();

JsonObject requestBody = new JsonObject();
JsonObject taxes = new JsonObject();

taxes.addProperty("expenseDeduction", 15321.99);

requestBody.add("taxes", taxes);

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, requestBody.toString());
Request request = new Request.Builder()
  .url("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020")
  .put(body)
  .addHeader("Accept", "application/json")
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer <<apiKey>>")
  .build();

Response response = client.newCall(request).execute();
package main

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

func main() {

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

    var requestBody = []byte(`{
        "taxes": {
            "expenseDeduction": 15321.99
        }
    }`)

    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/2020");
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 {
    expenseDeduction = 15321.99
  }
});
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/2020")
requestBody = {
  taxes: {
    expenseDeduction: 15321.99
  }
}

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

Field

Description

expenseDeduction

The total business expense deduction for this user. Most business expenses are deducted at 100% of the expense value. However, it’s important to note that expenses related to categories, such as "Meals & Entertainment," are deducted at a different rate.

The response from this API call is the same as detailed in the Retrieve User's YTD Taxes guide.

Adjusting for W-2 Income

Some self-employed individuals also have a W-2 job. Including your user's W-2 salary will improve the accuracy of our tax calculations. Do this by updating the w2Income value by calling the PUT /users/{userId}/taxes/{year} API endpoint.

curl \
  --request PUT \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020 \
  --header 'Authorization: Bearer <<apiKey>>' \
  --header 'Content-Type: application/json' \
  --data '{
    "taxes": {
      "w2Income": 60000
    }
  }'
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>>",
    "2020",
    {
      w2Income: 60000,
    }
  );
  
  console.log(response);
})();
import requests

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

payload = {"taxes": {"w2Income": 60000}}
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.squareup.okhttp.*;
// import com.google.gson.JsonObject;

OkHttpClient client = new OkHttpClient();

JsonObject requestBody = new JsonObject();
JsonObject taxes = new JsonObject();

taxes.addProperty("w2Income", 60000);

requestBody.add("taxes", taxes);

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, requestBody.toString());
Request request = new Request.Builder()
  .url("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxes/2020")
  .put(body)
  .addHeader("Accept", "application/json")
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer <<apiKey>>")
  .build();

Response response = client.newCall(request).execute();
package main

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

func main() {

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

    var requestBody = []byte(`{
        "taxes": {
            "w2Income": 60000
        }
    }`)

    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/2020");
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 {
    w2Income = 60000
  }
});
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/2020")
requestBody = {
  taxes: {
    w2Income: 60000
  }
}

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

Field

Description

w2Income

The user’s expected annual W2 income (if applicable). This number informs the tax bracket to be used when calculating the taxes owed on 1099 income. The taxes owed on this income are not included in the tax totals returned, as it is assumed to be already withheld by the employer.

The response from this API call is the same as detailed in the Retrieve User's YTD Taxes guide.


Did this page help you?