Skip to content

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