Tax Exchange Format (TXF) Conversion
Application Program Interface (API)

 

Description of the API

Partnerships electronically submit their federal Schedule K-1 data in Tax Exchange Format (TXF) to Schedule K-1.com for hosting on Open Financial Exchange (OFX) servers of ScheduleK-1.com.

K-1 recipients can then import data directly into tax preparation software, including TurboTax Online Edition.

Video Overview

API Endpoint

URL https://schedulek-1.appspot.com/api/v1/txf2ofx
Method POST

API Parameters

returnType A string identifying the type of response to be received from the API. Allowed values are: "XML", "JSON", "HTML", or "PDF". The pdf option returns an instruction sheet for importing data into tax software. The html option returns a "div" with links to download an instruction sheet for importing data into tax software. The xml and json options return data that can be consumed by the calling application.
appId A string identifying your application used to generate the K-1 data. (Letters, numbers, no spaces.)
apiToken A string assigned to you by SCHEDULEK-1.COM to authorize your use of the API. Email support@schedulek-1.com to request API token.
txf The K-1 data in TXF format.

You can test the API with the below html form

Example Java Implementation of the API

The below code and complete Maven project is also available at github.com/iTipsDev/k1-api-java-client

package local; // Change to reflect whatever folder you want to place this .java file in

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils; // <-- You will have to download this .jar file if you do not already have this


public class TXF2OFX {

    // Your application id
    public final String APP_ID = "MY_APP_ID"; // <-- Change this

    // Your assigned api token
    public final String API_TOKEN = "MY_TOKEN"; // <-- Change this

    // Whether to output certain status information as progresses
    public Boolean isVerbose = true; // <-- Change this, if not wanted
    
    // URL of web service
    public final String TARGET_URL = "https://schedulek-1.appspot.com/api/v1/txf2ofx";

    // Character set 
    public final String CHAR_SET = "UTF-8";
    
    // Possible return types
    public final String RETURN_TYPE_JSON = "JSON";
    public final String RETURN_TYPE_XML  = "XML";
    public final String RETURN_TYPE_PDF  = "PDF";
    public final String RETURN_TYPE_HTML = "HTML";

    
    
    public static void main( String[] args ) throws IOException {

        // File containing txf content
        String txfFile = "txf2ofx_input.txf"; // <-- Change this
        // Get the txf content
        String txfContent = readFile( txfFile );
        
        // Path and name of output file to generated (not including extension);
        String outputFile = "txf2ofx_output"; // <-- Change this
        
        // Execute the API
        TXF2OFX txf2ofx = new TXF2OFX( );
        txf2ofx.doAPI( txfContent, outputFile );
        
    }
    
    public void doAPI( String txfContent, String outputFile ) throws IOException {
        
        // Type of output to be returned by API
        String returnType = RETURN_TYPE_PDF;  // <-- Change this, if other return type wanted
//      String returnType = RETURN_TYPE_HTML; // <-- Change this, if wanted
//      String returnType = RETURN_TYPE_JSON; // <-- Change this, if wanted
//      String returnType = RETURN_TYPE_XML;  // <-- Change this, if wanted

        // API parameters
        Map kvMap = new HashMap( );
        kvMap.put( "appId", APP_ID );
        kvMap.put( "apiToken", API_TOKEN );
        kvMap.put( "returnType", returnType );
        kvMap.put( "txf", txfContent );
        
        // Do HTTP POST request, get HTTP response
        byte[ ] bytes = this.postFormURLEncoded( TARGET_URL, kvMap );
        
        // Write response to file
        String completeOutputFile = outputFile + "." + returnType.toLowerCase( );
        this.writeToFile( bytes, completeOutputFile );
        if ( this.isVerbose ) {
            System.out.println( completeOutputFile + " written." );
        }

    }
    
    public byte[] postFormURLEncoded( String targetUrl, Map kvMap ) throws IOException {
    
        long startTime = say( "Begin" );
        
        byte[] outputBytes = new byte[1];
    
        String queryString = this.buildQueryString( kvMap );
        
        this.say( "Query string: " + queryString );
        
        URL url = new URL( targetUrl );

        // Send HTTP request
        HttpURLConnection connection = (HttpURLConnection) url.openConnection( );
        connection.setDoOutput( true );
        connection.setInstanceFollowRedirects( false );
        connection.setRequestProperty( "Accept-Charset", CHAR_SET );
        connection.setRequestMethod( "POST" );
        connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded;charset=" + CHAR_SET );
        
        OutputStream output = connection.getOutputStream( );
        output.write( queryString.getBytes( CHAR_SET ) );
        output.close( );
    
        this.say( "Request sent" );


        // GET HTTP RESPONSE
        int responseCode = connection.getResponseCode( );
        
        this.say( "Response code: " + responseCode );
        
        if ( responseCode == HttpURLConnection.HTTP_OK ) {
        
            this.say( "Getting input stream" );
            InputStream is = connection.getInputStream( );
            outputBytes = IOUtils.toByteArray( is );
            this.say( "Byte count: " + outputBytes.length );
        
        }
        else {
    
            this.say( "Getting error stream" );
            InputStream errorStream = connection.getErrorStream( );
            String errorContent = this.convertInputStreamToString( errorStream );
            this.say( "Error explanation: " + errorContent );
    
        }
        
        long endTime = this.say( "End" );
        
        this.say( "Elapsed time: " + (endTime - startTime ) );
    
        return outputBytes;

    }
    
    public long say( String message ) {
        
        long millis = 0;
        
        if ( this.isVerbose ) {
        
            millis = System.currentTimeMillis( );
            
            System.out.print( "" + millis + " : " );
            
            System.out.println( "" +  message );
    
        }
        
        return millis;
    
    }
    
    public String buildQueryString( Map kvMap ) throws UnsupportedEncodingException {

        // Build query string from Map
        
        StringBuilder sb = new StringBuilder( );
        
        Boolean isFirst = true;
        for ( Map.Entry entry : kvMap.entrySet( ) ) {
            
            String key = entry.getKey( );
            String value = entry.getValue( );
            
            if ( isFirst ) {
                isFirst = false;
            }
            else {
                sb.append( "&" );
            }

            sb.append( String.format( 
                                      key + "=%s", 
                                      URLEncoder.encode( value, CHAR_SET ) 
                                    ) 
                     );
            
        }
        
        return sb.toString( );
        
    }
    
    public String convertInputStreamToString( InputStream inputStream ) throws IOException {
        
        String str = new String( );
        
        StringWriter writer = new StringWriter( );
        
        IOUtils.copy(inputStream, writer, CHAR_SET);
        
        str = writer.toString();
        
        return str;

    }

    public void writeToFile( byte[ ] bytes, String filePath ) throws IOException {
        
        FileOutputStream output = new FileOutputStream( new File( filePath ) );
        
        IOUtils.write( bytes, output );
        
    }
    
    public static String readFile( String fileName ) throws IOException {

        String content = "";
        
        File f = new File( fileName );
        if ( f.exists( ) ) {
            // good
        }
        else {
            System.err.println( fileName + " does not exist" );
            return content;
        }
        
        FileInputStream is = new FileInputStream( f );
        
        ByteArrayOutputStream buffer = new ByteArrayOutputStream( );
        
        int len;
        byte[ ] data = new byte[50000];
        while ( (len = is.read(data, 0, data.length) ) != -1) {
            buffer.write( data, 0, len );
        }
        buffer.flush( );
        is.close( );

        content = buffer.toString( );
        
        return content;
        
    }   

}

Example C Sharp / ASP.NET Web Forms Implementation of the API

The below code and complete Visual Studio project is also available at github.com/iTipsDev/k1-asp-net

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Async="true" Inherits="_Default" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Submit TXF for OFX Hosting</title>
</head>
<body>
    <form id="TXF2OFXForm" runat="server">
    <div>
        <asp:Label ID="SectionTitle" runat="server" Text="Import Directly Into Tax Software"></asp:Label>
        <div>
            Click the button below to push your K-1 data to the OFX servers of Schedule K-1.com 
            for direct import into tax software.   
        </div>
        <asp:Button ID="SubmitButton" runat="server" Text="Submit" OnClick="SubmitButton_Click" />
    </div>
    </form >

    <asp:Label ID="OFXImportInstructions" runat="server" Text=""></asp:Label>
</body>
</html>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void SubmitButton_Click(object sender, EventArgs e)
    {
        SubmitData();
    }

    protected async void SubmitData()
    {
        var client = new HttpClient();

        // Base URL
        client.BaseAddress = new Uri("https://schedulek-1.appspot.com");

        // Form parameters and values
        var postData = new List<KeyValuePair<string, string>>();
        postData.Add(new KeyValuePair<string, string>("returnType", "HTML"));
        postData.Add(new KeyValuePair<string, string>("appId", "YOUR_APP_ID"));
        postData.Add(new KeyValuePair<string, string>("apiToken", "YOUR_API_TOKEN"));
        postData.Add(new KeyValuePair<string, string>("txf", GetTXF()));
        HttpContent httpContent = new FormUrlEncodedContent(postData);

        // Post to server
        var response = client.PostAsync("api/v1/txf2ofx", httpContent).Result;

        // Place response content into div
        if (response.IsSuccessStatusCode)
        {
            var htmlResponse = await response.Content.ReadAsStringAsync();
            OFXImportInstructions.Text = htmlResponse;
        }
        else
        {
            var problemMessage = "Problem: " + response.StatusCode + " " + response.ReasonPhrase;
            OFXImportInstructions.Text = problemMessage;
        }

    }

    protected string GetTXF()
    {
        // Retrieve the applicable TXF content as string from  file system or database or other datastore
        string txfContent = "";

        txfContent = File.ReadAllText(Server.MapPath("~/txfdata/samplefile.txf.txt"));

        return txfContent;
    }

}