OpenTIN Technical documentation

/tin_validate/{country}/{type}/{tin}

Response samples

  {
    "tin_valid": 0,
    "message": "string",
    "ctry_spec_ver": "string",
    "ctry_spec_chk_dt": "string"
  }
              
TIN Validation API

Download OpenAPI specification: Download

This API allows to validate a TIN number against OECD specifications



Validate TIN
PATH PARAMETERS
country
required
string
Example: USA
The country of the TIN number in either Alpha-2 or Alpha-3 format of the ISO 3166-1 specification
type
required
string
Example: I
The type of the TIN number. Only two values are accepted, I for Individuals or E for Entities
tin
required
string
Example: 123-456/789
The type of the TIN number. Only two values are accepted, I for Individuals or
Responses
200 response
Response Headers
Access-Control-Allow-Origin
string
Response Schema: application/json
tin_valid
integer
message
string
ctry_spec_ver
string
ctry_spec_chk_dt
string

(English)


# OpenTIN API full example code

import sys
import traceback
import json
import boto3
from datetime import datetime
import os

import pytz
tz_FR = pytz.timezone('Europe/Berlin') 
    

def running_on_aws_mwaa():
    if 'AWS_EXECUTION_ENV' in os.environ:
        return True
    else:
        return False
    

if running_on_aws_mwaa():
    mysession = boto3.session.Session(region_name='eu-central-1')
else:
    mysession = boto3.session.Session(profile_name='___AWS_PROFILE_NAME___', region_name='eu-central-1')

try:
    print('-----------------------------------------------------------')
    dex = mysession.client('dataexchange', region_name='eu-central-1')

    response = dex.list_data_sets(
        MaxResults=200,
        Origin='ENTITLED'
    )

    # print(response)
    # print(response['DataSets'])
    most_recent_time = datetime(2022, 1, 1, 0, 0, 0, 0, tzinfo=tz_FR)
    for r in response['DataSets']:
        # print(r)
        if r['UpdatedAt'] > most_recent_time and 'TIN' in r['Name'] and 'API' in r['Name']:
            print("Found matching DataSet:", r['Id'])
            dataset_id = r['Id']
            most_recent_time = r['UpdatedAt']
    print('-----------------------------------------------------------')

    response = dex.list_data_set_revisions(
        DataSetId=dataset_id,
        MaxResults=200
    )
    # print(response)
    # print(response['Revisions'])
    most_recent_time = datetime(2022, 1, 1, 0, 0, 0, 0, tzinfo=tz_FR)
    for r in response['Revisions']:
        # print(r)
        if r['UpdatedAt'] > most_recent_time:
            print("Found matching Revision:", r['Id'])
            revision_id = r['Id']
            most_recent_time = r['UpdatedAt']

    print('-----------------------------------------------------------')

    response = dex.list_revision_assets(
        DataSetId=dataset_id,
        MaxResults=200,
        RevisionId=revision_id
    )
    # print(response)
    # print(response['Assets'])
    most_recent_time = datetime(2022, 1, 1, 0, 0, 0, 0, tzinfo=tz_FR)
    for r in response['Assets']:
        # print(r)
        if r['UpdatedAt'] > most_recent_time:
            print("Found matching Asset:", r['Id'])
            asset_id = r['Id']
            most_recent_time = r['UpdatedAt']
    print('-----------------------------------------------------------')
except Exception as e:
    print("EXCEPTION:", e)
    # Set some defaults, for example an asset_id/dataset_id/revision_id that was tested as working in the past
    asset_id = '__SOME_DEFAULT_FALUE__'
    dataset_id = '__SOME_DEFAULT_FALUE__'
    revision_id ='__SOME_DEFAULT_FALUE__'

try:
    tin_country = 'US'
    user_type_id = 'I'
    tin = '123456789'

    path = f'''/tin_validate/{tin_country}/{user_type_id}/{tin}'''
    print("Calling OpenTIN API using the path:", path)

    response = dex.send_api_asset(
        Body='',
        QueryStringParameters={},
        AssetId=asset_id,
        DataSetId=dataset_id,
        RequestHeaders={},
        Method='GET',
        Path=path,
        RevisionId=revision_id
    )

    print(response['Body'])
    str_answer = response['Body']
    opentin_answer = json.loads(response['Body'])
    if 'tin_valid' in opentin_answer:
        print('tin_valid:', opentin_answer['tin_valid'])
    if 'message' in opentin_answer:
        print('message:', opentin_answer['message'])

except Exception as e:
    print("Exception calling OpenTIN API:", e)

# OpenTIN API full example code END

 

(English)


-"Invalid request syntax, please check the documentation"
# The API didn't understand your request at all

- "The country code must be a valid ISO 3166-1 Alpha-2 OR Alpha-3 code"
# The country code must be 2 or 3 characters long and from the ISO 3166-1 standard

- "Error: the parameter 'entity_type' must be either I for individuals or E for entities"
- "The type of the TIN number must be either E for entities or I for individuals"
# The entity type can be only "I" for Individuals (physical persons) or "E" for Entities (Companies)

- "Internal TIN validation error"
# The API unexpedly crashed

- "Error: Unsupported ISO3 country code"
- "Error: Unsupported ISO2 country code"
# The TIN validation for this country is not yet implemented (contact our support if you encounter this rare case)

- "Error: Invalid ISO2 country code"
# The country you specified using a ISO2 code is not part of the 3166-1 standard

- "Error: the parameter 'tin' is mandatory"
# The TIN parameter was not found in the request

- "Error: the parameter 'entity_type' is mandatory"
# The "entity_type" parameter was not found in the request

- "Error: The TIN length is invalid"
# The number you provided doesn't seem to be long enough to be a valid TIN

- "This country is not a member of OECD"
# The provided country isn't participating in the OECD CRS initiative

- "This country does not use TINs"
# This country doesn't have any equivalent of Tax Identification Numbers

- "No validation available for this type of entity for this country"
# All implemented countries there is a validation available for Individuals
# For certain countries a validation for Entities is also available

- "Error: the TIN has invalid length for the specified country"
# The length of the TIN number is not valid for the specified country

- "Error: the TIN's format is invalid for the specified country"
# The format of the TIN doesn't follow the official specification for this country

- "Error: the TIN's checksum is invalid for the specified country"
# The vast majority of countries use complex checksum algorithms to ensure the TIN number is valid. This test failed for the provided TIN/country pair

- "Error: the TIN's structure is invalid for the specified country"
# The rules for the structure of the TIN failed for the provided TIN/country pair

- "Error: Unsupported checksum type"
# Internal error that should never be seen by the API users

- "The TIN is valid"
# The message that we want to see the most! The TIN passed all the available structure checks

(English)

using System;
using System.Threading.Tasks;
using Amazon.DataExchange;
using Amazon.DataExchange.Model;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon;

/*
// .csproj file:

  
    Exe
    netcoreapp8
  
  
    
    
  
  

*/
namespace AwsDataExchangeSample
{
  class Program
  {
    static void Main(string[] args)
    {
        var chain = new CredentialProfileStoreChain();
        AWSCredentials awsCredentials;
        if (chain.TryGetAWSCredentials("credentials-profile-name", out awsCredentials))
        {
            // Connect to Data Exchange
            AmazonDataExchangeClient client = new AmazonDataExchangeClient(awsCredentials, RegionEndpoint.EUCentral1);

            // List the APIs we subscribed to
            ListDataSetsRequest listDataSetsRequest = new ListDataSetsRequest();
            listDataSetsRequest.Origin = "ENTITLED";

            Task dataSetsRequestTask = client.ListDataSetsAsync(listDataSetsRequest);
            dataSetsRequestTask.Wait();

            string tin_validation_api_id = System.String.Empty;
            foreach (DataSetEntry dataSetEntry in dataSetsRequestTask.Result.DataSets)
            {
                Console.WriteLine("{0}/{1}: {2}\n  {3}",
                    dataSetEntry.OriginDetails.ProductId,
                    dataSetEntry.Id,
                    dataSetEntry.Name,
                    dataSetEntry.Description);

                if (dataSetEntry.Name == "TIN Validation API")
                    tin_validation_api_id = dataSetEntry.Id;
            }
            Console.WriteLine("--> OK found the TIN Validation API id: {0}\n", tin_validation_api_id);

            // List the API revisions and find the latest one
            ListDataSetRevisionsRequest listDataSetRevisionsRequest = new ListDataSetRevisionsRequest();
            listDataSetRevisionsRequest.DataSetId = tin_validation_api_id;

            Task dataSetRevisionsTask = client.ListDataSetRevisionsAsync(listDataSetRevisionsRequest);
            dataSetRevisionsTask.Wait();

            string tin_validation_api_latest_revision_id = System.String.Empty;
            DateTime tin_validation_api_latest_revision_date = new DateTime(2000,01,01);
            foreach (RevisionEntry dataSetRevision in dataSetRevisionsTask.Result.Revisions)
            {
                Console.WriteLine("{0} - [{1}] / [{2}]",
                    dataSetRevision.Id,
                    dataSetRevision.UpdatedAt,
                    dataSetRevision.Comment);

                if (dataSetRevision.UpdatedAt > tin_validation_api_latest_revision_date)
                {
                    tin_validation_api_latest_revision_id = dataSetRevision.Id;
                    tin_validation_api_latest_revision_date = dataSetRevision.UpdatedAt;
                }
            }
            Console.WriteLine("--> OK found the id of the latest revision of the TIN Validation API: {0}\n", tin_validation_api_latest_revision_id);

            // List the assets of the revison and find the latest one
            ListRevisionAssetsRequest listRevisionAssetsRequest = new ListRevisionAssetsRequest();
            listRevisionAssetsRequest.DataSetId = tin_validation_api_id;
            listRevisionAssetsRequest.RevisionId = tin_validation_api_latest_revision_id;

            Task dataSetAssetsTask = client.ListRevisionAssetsAsync(listRevisionAssetsRequest);
            dataSetAssetsTask.Wait();

            string tin_validation_api_latest_asset_id = System.String.Empty;
            DateTime tin_validation_api_latest_asset_date = new DateTime(2000,01,01);
            foreach (AssetEntry dataSetAsset in dataSetAssetsTask.Result.Assets)
            {
                Console.WriteLine("{0} - [{1}] / [{2}]",
                    dataSetAsset.Id,
                    dataSetAsset.UpdatedAt,
                    dataSetAsset.Name);

                if (dataSetAsset.UpdatedAt > tin_validation_api_latest_asset_date)
                {
                    tin_validation_api_latest_asset_id = dataSetAsset.Id;
                    tin_validation_api_latest_asset_date = dataSetAsset.UpdatedAt;
                }
            }
            Console.WriteLine("--> OK found the id of the latest asset of the TIN Validation API revision: {0}\n", tin_validation_api_latest_asset_id);

            // Call the API
            SendApiAssetRequest apiRequest = new SendApiAssetRequest();
            apiRequest.DataSetId = tin_validation_api_id;
            apiRequest.RevisionId = tin_validation_api_latest_revision_id;
            apiRequest.AssetId = tin_validation_api_latest_asset_id;
            apiRequest.Method = "GET";
            apiRequest.Body = "";

            string tin_country = "US";
            string user_type_id = "I";
            string tin = "123456789";

            string path = $"""/tin_validate/{tin_country}/{user_type_id}/{tin}""";
            Console.WriteLine("Calling OpenTIN API using the path:{0}", path);
            apiRequest.Path = path;

            Task apiResponseTask = client.SendApiAssetAsync(apiRequest);
            apiResponseTask.Wait();

            Console.WriteLine("--> Open TIN API response:{0}", apiResponseTask.Result.Body);
        
        }
        else {
            Console.WriteLine("profile not found in your credentials file");
        }
    }
  }
}