Statement Documentation¶
Information about the various statements supported by the API is available from two sources. First the documentation is available using GraphQL's introspection tools. You can use a simple program, command-line tools, or a GUI to view this form of the documentation. See the viewing documentation page for information about using a GUI tool to view the documentation.
Statement Definitions Query¶
The API also provides a query with information about each supported statement. The query takes the following format:
query {
statementDefinitions {
definitions {
identifier
name
title
description
recipientName
senderName
blankForm
fields {
identifier
arrayType
boxLabel
boxNumber
dataType
description
fixedArrayLength
frequentUse
maxArrayLength
maxStringLength
sampleValue
sortOrder
yearsUsed
}
}
errors
}
}
Each definition returns the following elements:
- identifier: The string used by the API to identify the statement type.
- name: The name of the form, as defined by the tax authority that issues it.
- title: The title of the form, as defined by the tax authority that issues it.
- description: A short description of the form and its purpose.
- recipientName: Name of the recipient as it appears on the form, for example employee for W-2 or recipient for 1099-NEC.
- senderName: Name of the sender as it appears on the form, for example employer for W-2 or payer for 1099-NEC.
- blankForm: A blank, sample version of the form encoded in base 64. See downloading PDFs for information about decoding and saving encoded PDF data.
- fields: A list of fields present on the statement. Each field includes the following elements:
- identifier: The name used by the API to identify this field when setting or retrieving data.
- arrayType: The type of elements in the array, if the dataType is array, otherwise null.
- boxLabel: The label of the box in which this element appears.
- boxNumber: The number of the box in which this element appears.
- dataType: The data type of this element. Valid values are: array, boolean, character, date, decimal, integer, money, phone_number, state, text, tin, and zip_code.
- description: A short description of this field.
- fixedArrayLength: The number of elements which must appear in this array if this field is of dataType array and of fixed length, otherwise null.
- frequentUse: True if, in OtterTax's estimation, this field is used frequently.
- maxArrayLength: The maximum number of elements which can appear in this array if this field is of dataType array and of variable length, otherwise null.
- maxStringLength: The maximum number of characters which can appear in this string if this field is of dataType text, otherwise null.
- sampleValue: A sample value for this field.
- sortOrder: The approximate order in which this field appears on the form.
- yearsUsed: A list of tax years for which this field is valid.
The code snippets below illustrate running the query. See the documentation on authentication for information about obtaining the credential data passed in the header.
# Terminate lines with \ character to allow command to span multiple lines.
# Use here document for data stream.
# Tested using the bash interpreter on Linux.
curl 'https://sandbox.ottertax.com/v2/graphql' \
-i \
-X POST \
-H 'content-type: application/json' \
-H 'access-token: YOUR ACCESS TOKEN' \
-H 'client: YOUR CLIENT ID' \
-H 'uid: YOUR UID' \
-d @- <<END_DATA
{
"query":"
query {
statementDefinitions {
definitions {
identifier
name
title
description
recipientName
senderName
blankForm
fields {
identifier
arrayType
boxLabel
boxNumber
dataType
description
fixedArrayLength
frequentUse
maxArrayLength
maxStringLength
sampleValue
sortOrder
yearsUsed
}
}
errors
}
}
"
}
END_DATA
:: Terminate lines with ^ character to allow command to span multiple lines.
:: Precede quotation marks in data stream with single backslashes.
:: Tested using a command prompt on Windows 10.
curl "https://sandbox.ottertax.com/v2/graphql" ^
-i ^
-X POST ^
-H "content-type: application/json" ^
-H "access-token: YOUR ACCESS TOKEN" ^
-H "client: YOUR CLIENT ID" ^
-H "uid: YOUR UID" ^
-d "{ \"query\":\" ^
query { ^
statementDefinitions { ^
definitions { ^
identifier ^
name ^
title ^
description ^
recipientName ^
senderName ^
blankForm ^
fields { ^
identifier ^
arrayType ^
boxLabel ^
boxNumber ^
dataType ^
description ^
fixedArrayLength ^
frequentUse ^
maxArrayLength ^
maxStringLength ^
sampleValue ^
sortOrder ^
yearsUsed ^
} ^
} ^
errors ^
} ^
} ^
\" }"
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
// This example uses version 2.9.1 of the
// open source gson library from Google.
// See https://github.com/google/gson.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
// This example uses httpclient (version 4.5.13)
// and httpcore (version 4.4.13) libraries of the
// open source Apache HttpComponents project.
// See https://hc.apache.org/index.html.
import org.apache.http.entity.StringEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
// Download the OtterTax java classes for the GraphQL
// query and mutation responses at
// https://github.com/OtterTax/graphql-java-classes
import com.ottertax.support.StatementDefinitionsResponse;
public class DefinitionDownloader {
private String endpoint = "https://sandbox.ottertax.com/v2/graphql";
private String accessToken = "YOUR ACCESS TOKEN";
private String client = "YOUR CLIENT ID";
private String uid = "YOUR UID";
private String gql =
String.join("\n",
"query {",
" statementDefinitions {",
" definitions {",
" identifier",
" name",
" title",
" description",
" recipientName",
" senderName",
" blankForm",
" fields {",
" identifier",
" arrayType",
" boxLabel",
" boxNumber",
" dataType",
" description",
" fixedArrayLength",
" frequentUse",
" maxArrayLength",
" maxStringLength",
" sampleValue",
" sortOrder",
" yearsUsed",
" }",
" }",
" errors",
" }",
"}");
private String querify(String rawGraphql) {
Gson gson = new Gson();
return("{\"query\":" + gson.toJson(rawGraphql) + "}");
}
private void download() {
CloseableHttpClient httpClient = HttpClients.createDefault();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String response = "";
try {
HttpPost httpPost = new HttpPost(endpoint);
httpPost.addHeader("content-type", "application/json");
httpPost.addHeader("access-token", accessToken);
httpPost.addHeader("client", client);
httpPost.addHeader("uid", uid);
StringEntity stringEntity = new StringEntity(querify(gql));
httpPost.setEntity(stringEntity);
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
StringBuffer responseBuffer = new StringBuffer();
String inputLine;
while ((inputLine = reader.readLine()) != null) {
responseBuffer.append(inputLine);
}
reader.close();
response = responseBuffer.toString();
int responseCode = httpResponse.getStatusLine().getStatusCode();
if( responseCode != 200 ) {
System.out.println("Response code from server was " + String.valueOf(responseCode) + ".");
}
httpResponse.close();
httpClient.close();
} catch(IOException e) {
System.out.println("Error posting GraphQL.\nExiting");
System.exit(1);
}
StatementDefinitionsResponse statementDefinitionsResponse = gson.fromJson(response, StatementDefinitionsResponse.class);
// Show the definitions.
System.out.println(gson.toJson(statementDefinitionsResponse));
}
public static void main(String[] args) {
DefinitionDownloader definitionDownloader = new DefinitionDownloader();
definitionDownloader.download();
}
}
// Using graphql-request from
// https://github.com/prisma-labs/graphql-request
// Example tested with node version 14.16.0
import { GraphQLClient, gql } from 'graphql-request'
async function main() {
const endpoint = 'https://sandbox.ottertax.com/v2/graphql'
const graphQLClient = new GraphQLClient(endpoint, {
headers: {
'access-token': 'YOUR ACCESS TOKEN',
'client': 'YOUR CLIENT ID',
'uid': 'YOUR UID'
},
})
const query = gql`
query {
statementDefinitions {
definitions {
identifier
name
title
description
recipientName
senderName
blankForm
fields {
identifier
arrayType
boxLabel
boxNumber
dataType
description
fixedArrayLength
frequentUse
maxArrayLength
maxStringLength
sampleValue
sortOrder
yearsUsed
}
}
errors
}
}
`
const data = await graphQLClient.request(query)
console.log(JSON.stringify(data))
}
main().catch((error) => console.error(error))
<?php
// Tested with php-cli version 8.0.5.
$query =<<<'END_DATA'
query {
statementDefinitions {
definitions {
identifier
name
title
description
recipientName
senderName
blankForm
fields {
identifier
arrayType
boxLabel
boxNumber
dataType
description
fixedArrayLength
frequentUse
maxArrayLength
maxStringLength
sampleValue
sortOrder
yearsUsed
}
}
errors
}
}
END_DATA;
$payload = array ('query' => $query);
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $payload ),
'header'=> "Content-Type: application/json\r\n" .
"access-token: YOUR ACCESS TOKEN\r\n" .
"client: YOUR CLIENT ID\r\n" .
"uid: YOUR UID\r\n"
)
);
$context = stream_context_create( $options );
$response = file_get_contents( 'https://sandbox.ottertax.com/v2/graphql',
false, $context );
if( $response === FALSE ) {
echo "Call to server failed.\n";
} else {
echo $response . "\n";
}
?>
# Using GQL from
# https://github.com/graphql-python/gql
# Tested using python version 3.8.8
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
transport = AIOHTTPTransport(url="https://sandbox.ottertax.com/v2/graphql",
headers={ 'access-token': 'YOUR ACCESS TOKEN',
'client': 'YOUR CLIENT ID',
'uid': 'YOUR UID' })
client = Client(transport=transport, fetch_schema_from_transport=True)
query = gql(
"""
query {
statementDefinitions {
definitions {
identifier
name
title
description
recipientName
senderName
blankForm
fields {
identifier
arrayType
boxLabel
boxNumber
dataType
description
fixedArrayLength
frequentUse
maxArrayLength
maxStringLength
sampleValue
sortOrder
yearsUsed
}
}
errors
}
}
"""
)
result = client.execute(query)
print(result)
# If you wish to use a library instead, see
# https://github.com/github/graphql-client
# Tested using ruby 2.7.2.
require( 'net/http' )
require( 'uri' )
require( 'json' )
uri = URI( "https://sandbox.ottertax.com/v2/graphql" )
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
headers = { 'Content-Type': 'application/json',
'access-token': 'YOUR ACCESS TOKEN',
'client': 'YOUR CLIENT ID',
'uid': 'YOUR UID' }
query = <<-END_DATA
query {
statementDefinitions {
definitions {
identifier
name
title
description
recipientName
senderName
blankForm
fields {
identifier
arrayType
boxLabel
boxNumber
dataType
description
fixedArrayLength
frequentUse
maxArrayLength
maxStringLength
sampleValue
sortOrder
yearsUsed
}
}
errors
}
}
END_DATA
request = Net::HTTP::Post.new(uri.request_uri, headers )
request.body = {query: query}.to_json
response = http.request(request)
if( response.code == '200' )
payload = JSON.parse( response.body )
STDOUT.puts( payload )
else
STDOUT.puts( "Response code was #{response.code}:\n#{response.inspect}" )
end