Skip to main content
Migrating from v1.7.3 to v2.0 View the migration guide for a full breakdown of what's changed and how to update your integration. View Migration Guide
Version: 2.0

OAuth 2.0 Authentication

TaxBandits uses OAuth 2.0 as the standard authorization protocol, allowing your application to securely access TaxBandits resources via token-based authentication. OAuth 2.0 is implemented using JSON Web Tokens (JWT), where you authenticate using a signed token (JWS) and receive an access token (JWT) in return. This access token is used in subsequent API calls.

The steps below walk through this exchange in detail — the endpoint to call, the exact structure of the signed token you send, the scope and category values TaxBandits accepts, and the response you receive back.

Step 1 — Retrieve Your Credentials

Log in to the TaxBandits Developer Console and retrieve the following credentials:

  • Client ID
  • Client Secret
  • User Token

Credential Reset

You can reset your API credentials at any time from the Developer Console. New credentials are generated immediately, and your previous credentials remain valid for up to 72 hours — giving you time to update your integration without disruption.

Step 2 — Generate the Incoming JWT (JWS)

Using your credentials, construct the JWT payload and sign it using the Client Secret with the HS256 algorithm. This produces a JWS.

The Client Secret is not included in the JWT payload. It is used only to generate the HS256 signature. The JWS is valid for 5 minutes from the time of issue. If the JWS expires before the request is submitted, generate a new one using the same credentials.

Optionally, set the Scope and Categories claims in the payload to restrict what the resulting JWT access token can access.

  • Scope — Controls which HTTP methods the token can use. Allowed values: Read, Write, Read_Write, Transmit, FullAccess.
  • Categories — Restricts the token to specific form groups. Required when scope is not FullAccess.

See Scope Values and Category Values for the full lists of accepted values and example combinations.

{
"alg": "HS256", /*Algorithm = HS256*/
"typ": "JWT" /*Type = JSON Web Token (JWT)*/
}

Payload:

{
"iss": "968a9c78dae29a29", /*Issuer: Client ID retrieved from the console site*/
"sub": "968a9c78dae29a29", /*Subject: Client ID retrieved from the console site*/
"aud": "a574b75f18b24fc09f9039ffb5cb08f3", /*Audience: User Token retrieved from the console site*/
"iat": 1516239022 /*Issued at: Number of seconds from Jan 1 1970 00:00:00 (Unix epoch format)*/
"scope": "fullaccess", /*(read / write / read_write / transmit / fullaccess)*/ --> Optional
"categories": ["all"] /* All, AddressBook, WhCertificate, Verifications, W21099*/ --> Optional
}

Signature:

The signature is produced by signing the Base64URL-encoded header and payload using your Client Secret with the HS256 algorithm:

    HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
siqHfLy59g3UHxrb5gjxg /*Client Secret retrieved from the console site*/
)

Sample JWS

Combine the Header, payload, and signature to generate the JWS.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOi
I5NjhhOWM3OGRhZTI5YTI5Iiwic3ViIjoiOTY4YTljNzhkYWUyOWEyOSIsImF1
ZCI6ImE1NzRiNzVmMThiMjRmYzA5ZjkwMzlmZmI1Y2IwOGYzIiwiaWF0IjoxN
TE2MjM5MDIyfQ.HNQznxlPyVt62kyUeVwtk1-uzm1uDWH4NBDLShA6Ac0

Step 3 — Submit the Token Request

The incoming authentication token is a signed JWT (JWS) that you generate using your Client Secret. Submit a POST request to the token endpoint below, including the JWS generated as the Bearer token in the Authentication header:

GETv2/token
HeaderValueRequired
AuthorizationBearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Rlc3RvYXV0aC5leHByZXNzYXV0aC5uZXQvdjIvIiwic3ViIjoiOWYzZTQwM2RlMWQ5YTNkMiIsImF1ZCI6ImNhNjRkNzMyMzBhNDRkMjY4MjkzN2I2ODQ0ZmJjNTI4IiwiaWF0IjoxNjk0NTg1NDU4LCJleHAiOjE2OTQ1ODkwNTh9.WPOCs-lxo3GXz7_zGGmQovWZy4WD0smW7n-U-InuoXEYes

TaxBandits validates the JWS, verifies your credentials, and returns an Access Token (JWT) in the response. This JWT is what you use in all subsequent API calls.

Success response

{
"StatusCode": 200,
"StatusName": "Ok",
"StatusMessage": "Successful API call",
"AccessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Rlc3RvYXV0aC5leHByZXNzYXV0aC5uZXQvdjIvIiwic3ViIjoiOWYzZTQwM2RlMWQ5YTNkMiIsImF1ZCI6ImNhNjRkNzMyMzBhNDRkMjY4MjkzN2I2ODQ0ZmJjNTI4IiwiaWF0IjoxNjk0NTg1NDU4LCJleHAiOjE2OTQ1ODkwNTh9.WPOCs-lxo3GXz7_zGGmQovWZy4WD0smW7n-U-InuoXE",
"TokenType": "Bearer",
"ExpiresIn": 3600,
"Errors": null
}

Error response

When a request fails, AccessToken is null, and Errors is populated with details. All authentication failures return a 401 Unauthorized status.

Error IDWhen It Occurs
AUTH-100002The Authentication header is missing or empty from the request
AUTH-100005The JWS cannot be validated — the signature is incorrect, the token is malformed, or the JWS has expired. Note: JWS is valid for 5 minutes from issue.
AUTH-100048The scope value in the JWS payload does not match one of the accepted values: Read, Write, Read_Write, Transmit, FullAccess
AUTH-100051One or more values in Categories do not match a recognized form group. Refer to the Category Values reference table for accepted values.

Sample Error JSON

{
"StatusCode": 401,
"StatusName": "Unauthorized",
"StatusMessage": "Invalid credentials",
"AccessToken": "null",
"TokenType": "null",
"ExpiresIn": 0,
"Errors": [
{
"Id": "AUTH-100005",
"Name": "Authentication",
"Message": "Invalid JWS"
}
]
}

Step 4 — Use the JWT Access Token

Include the AccessToken from the response as a Bearer token in the Authorization header of all subsequent API calls:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Rlc3RvYXV0aC5leHByZXNzYXV0aC5uZXQvdjIvIiwic3ViIjoiOWYzZTQwM2RlMWQ5YTNkMiIsImF1ZCI6ImNhNjRkNzMyMzBhNDRkMjY4MjkzN2I2ODQ0ZmJjNTI4IiwiaWF0IjoxNjk0NTg1NDU4LCJleHAiOjE2OTQ1ODkwNTh9.WPOCs-lxo3GXz7_zGGmQovWZy4WD0smW7n-U-InuoXE

The JWT access token is valid for 1 hour (3600 seconds) from the time of issue. Once expired, you must generate a new JWS and submit a new token request to obtain a fresh JWT.

Reference

The following tables provide the complete list of accepted scope and Categories values, along with examples of how each combination affects the resulting JWT access token.

Scope Values

The scope claim determines which HTTP methods the resulting access token is permitted to use.

ScopeHTTP Methods GrantedRestrictions
ReadGETCannot create, update, delete, or transmit.
WritePOST, PUT, DELETEExcludes the Transmit endpoint.
Read_WriteGET, POST, PUT, DELETEExcludes the Transmit endpoint.
TransmitGET, POST (limited to Transmit)POST access applies only to the Transmit endpoint, not to Create or Update.
FullAccessAll methodsNo restrictions.
  • If the submitted scope value does not match one of the five values above, the request fails with “Invalid scope”.

  • If scope is set to anything other than FullAccess, the Categories claim becomes required.

Category Values

The Categories claim determines which form group(s) the resulting access token is authorized to act on. It is optional when scope is FullAccess — if omitted, the token has access across all categories.

Rules:

  • When scope is FullAccess, and Categories is omitted, the token is granted access across all form groups.
  • When scope is anything other than FullAccess, Categories is required.
  • When Categories is provided, the token is authorized only for the listed form groups — regardless of scope.
  • If a value in Categories does not match a recognized form group, the request fails with “Invalid categories”.

Accepted values:

TypeAccepted Values
GeneralAll, AddressBook, Business, Recipient
Verification & ComplianceWhCertificate, FormW9, Verifications, TIN Match, KYC, KYB
1099 / W-2 FormsW21099, W2, 1099, 1042-S, 3921, 5498, Form5498, Form5498ESA, Form5498SA, 1098, Form1098, Form1098E, Form1098T, W2G, Other 1099 Forms, Corrections
94x Series94x, 941, 940, 943, 944, 945, PINRequest, Amendments
ACAACA, 1095-B and 1095-C
ExtensionsExtension, Form8809, Form15397, Form4868, Form7004
State PayrollStatePayroll, New Hire, Withholding, UnEmployment
Account & UtilitiesUtilities, EmailCustomization, PortalCustomization, OnlineAccess, Utility, TeamMember, Attachment, Reports

Scope and Category Combination

An issued access token is authorized only for the intersection of its scope and Categories values. The following scenarios illustrate how each combination resolves in practice.

Scenario A — Read scope, 1099 category

  • Grants access to 1099 GET methods only: Get, List, Status, Validate, GetPdf.
  • No access to GET methods for other categories, and no access to any non-GET method.

Scenario B — Write scope, W2 category

  • Grants access to W2 POST, PUT, DELETE methods: Create, ValidateForm, Update, RequestDraftPdfUrl, RequestPdfUrls, Delete.
  • No access to POST, PUT, or DELETE methods for other categories.

Scenario C — Read_Write scope, 94x category

  • Grants access to all 94x GET, POST, PUT, DELETE methods: Get, List, Status, Validate, GetPdf, Create, ValidateForm, Update, RequestDraftPdfUrl, RequestPdfUrls, Delete.
  • No access to methods for other categories. Transmit remains inaccessible, as Read_Write excludes it regardless of category.

Scenario D — Transmit scope, 1099 category

  • Grants access to 1099 GET methods plus POST restricted to Transmit: Get, Status, Transmit.
  • No access to other categories' methods. Create, Update, and Delete remain inaccessible.

Scenario E — FullAccess scope, 1099 category

  • Grants access to all methods available for the 1099 form group.
  • No access to other categories, since Categories was explicitly specified.

Scenario F — Categories omitted

  • If Categories is omitted from the request entirely, the resulting token is granted access across all form groups, at whatever method-level restriction the specified scope imposes. Omitting Categories should be a deliberate choice — it removes form-group restriction regardless of scope.