Skip to content

Authentication

In order to access the core functionality of the OtterTax API, you must be authenticated. The API performs authentication by checking the HTTP headers for three values: access-token, client, and uid. These three values must be present in every call you make to the API or the call will fail.

To get a credential which includes these three values, send a request to the endpoint v2/auth/sign_in with a JSON payload as follows:

"email":    "<YOUR LOGIN EMAIL>",
"password": "<YOUR PASSWORD>"
The relevant values are returned in as header values.

The code snippets below illustrate how to get your credential in several different languages.

# Terminate lines with \ character to allow command to span multiple lines.
# Escape quotation marks in data stream with single backslashes.
# Tested using the bash interpreter on Linux.
curl 'https://sandbox.ottertax.com/v2/auth/sign_in' \
  -i \
  -X POST \
  -H 'content-type:  application/json' \
  -d "{ \"email\": \"YOUR LOGIN EMAIL\", \"password\": \"YOUR PASSWORD\" }"
# Output contains values for access-token, client, and uid
:: Terminate lines with ^ character to allow command to span multiple lines.
:: Escape quotation marks in data stream with single backslashes.
:: Tested using a command prompt on Windows 10.
curl "https://sandbox.ottertax.com/v2/auth/sign_in" ^
  -i ^
  -X POST ^
  -H "content-type: application/json" ^
  -d "{ \"email\": \"YOUR LOGIN EMAIL\", \"password\": \"YOUR PASSWORD\" }"
:: Output contains values for access-token, client, and uid
// If using node, be sure to install and require node-fetch.
// Example tested with node version 14.16.0
const fetch = require("node-fetch");

const data = { email:    "YOUR LOGIN EMAIL",
               password: "YOUR PASSWORD" };
fetch( "https://sandbox.ottertax.com/v2/auth/sign_in",
      { method: "POST",
        headers: {"content-type": "application/json"},
        body: JSON.stringify(data) })
.then(response => {
  const accessToken = response.headers.get('access-token');
  const client = response.headers.get('client');
  const uid = response.headers.get('uid');
  console.log( 'access-token: ', accessToken );
  console.log( 'client:       ', client );
  console.log( 'uid:          ', uid );
})
.catch(err => console.log(err));
<?php
// Tested with php-cli version 8.0.5.
$data = array( 'email'    => 'YOUR LOGIN EMAIL',
               'password' => 'YOUR PASSWORD' );
$options = array(
  'http' => array(
    'method'  => 'POST',
    'content' => json_encode( $data ),
    'header'=>  "Content-Type: application/json\r\n"
    )
);

$context  = stream_context_create( $options );
$response = get_headers( 'https://sandbox.ottertax.com/v2/auth/sign_in',
                         1, $context );
if( $response === FALSE ) {
  print "Call to server failed.\n";
} else {
  print "access-token: ${response['access-token']}\n";
  print "client:       ${response['client']}\n";
  print "uid:          ${response['uid']}\n";
}
?>
# Tested using python version 3.8.8
import urllib.request
import json

url = "https://sandbox.ottertax.com/v2/auth/sign_in"
data = {
    "email":    "YOUR LOGIN EMAIL",
    "password": "YOUR PASSWORD"  
}
headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
}
body = json.dumps(data).encode("utf-8")

try:
    req = urllib.request.Request(url, body, headers)
    with urllib.request.urlopen(req) as f:
        info = f.info()
    print(f"access-token: {info['access-token']}")
    print(f"client:       {info['client']}")
    print(f"uid:          {info['uid']}")
except Exception as e:
    print(e)
# Tested using ruby 2.7.2.
require( 'net/http' )
require( 'uri' )
require( 'json' )

uri = URI( "https://sandbox.ottertax.com/v2/auth/sign_in" )
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Post.new( uri.request_uri,
                               { 'Content-Type': 'application/json' } )
request.body = JSON.generate( {'email' =>   'YOUR LOGIN EMAIL',
                              'password' => 'YOUR PASSWORD'} )
response = http.request(request)
if( response.code == '200' )
  STDOUT.puts( "\nCredential:" )
  STDOUT.puts( "  access-token:  #{response['access-token']}" )
  STDOUT.puts( "  client:        #{response['client']}" )
  STDOUT.puts( "  uid:           #{response['uid']}" )
else
  STDOUT.puts( "Response code was #{response.code}:\n#{response.inspect}" )
end

Before moving on, you may wish to test your authentication by accessing a protected query.