In Tax Year 2021, Web Presentment API was renamed Online Access API.

Summary: The 1099 Pro web presentment API is used to interface into the 1099 Pro Corporate Suite software.  It can be used to search for tax forms and retrieve PDF copies.  The web presentment API is a Microsoft .Net 4.0 DLL with a SOAP web service wrapper.  The API consists of 4 web service operations and 1 web page.  Use the “RequestForms” web service method to get a list of PDF keys.  Then use the "RequestPdf" method or "pdf.aspx" page to get the actual PDF from the PDF key.

PDF Key Security Background: When you make a “RequestForms” call with the correct API key, private key, and HMAC signature (optional) the API searches the 1099 Pro database for forms matching the requested criteria.  When a form is found its unique identifier is noted.  Then the API concatenates a string that contains a time stamp, the form type, the forms unique ID, the PDF password to be applied, and an expiration date.  The string is then encrypted using 256-bit AES with a random initialization vector that is appended to the end of the cypher text and then all is base64 encoded.  This result is then passed back as the PDF Key.  When a request comes in for a PDF, the PDF key is base64 decoded and AES decrypted and the string is checked for proper formatting.  If it passes, we use the forms unique ID from the string to retrieve the tax form data and generate a PDF.  The symmetric key used for the AES encryption/decryption is a 256-bit key stored in the web.config.

  • https://your.site.com/xxx/api.asmx - A SOAP 1.1 and 1.2 XML web service.
    • FormList - Used for testing, returns a list of form types supported by this API.
    • RequestForms - Returns a list of PDF keys based on your search parameters.
    • RequestXml - Returns all of the individual records’ information (recipient info, box amounts, optional fields…) based on your search/filter parameters.
    • RequestPdf - Returns a specific PDF key’s PDF as a binary object.

  • https://your.site.com/xxx/pdf.aspx?key=[PDF Key] - Returns a specific PDF key’s PDF as a file download.  Used to
    provide direct download links.
  • RequestForms & RequestXml
    • Request XML Parameters.

+ API Security. Optional, but required if they are set in the web.config

ApiKey = 40 character random string that must match the one set in the web.config.

PrivateKey = 40 character random string that must match the one set in the web.config

Optional HMAC Security:  See the "Optional HMAC Signature Process" section below for more information.

Signature =

Base64 encoded HMAC SHA-256 hash of the request parameters.  
Timestamp =Timestamp used to invalidate the HMAC signature after a period of time.  The timestamp is UTC in the following format "10/28/2019 11:09:38 PM".  The time period is set in the web.config. 

+ PDF & Link Security. Optional.

Password = Optional- Dynamically set up to a 32 character string that will be required to open the PDF.

Expiration = Optional- Integer specifying how many days the PDF keys are good for.  Default is to not expire.

+ Search parameters. If a parameter is not set then it will return all.

Tin = Optional, 9-11 character string representing the recipients tin and tin type. 

      • xxx-xx-xxxx = match SSN only.
      • xx-xxxxxxx = match EIN only.
      • xxxxxxxxx = match, SSN, EIN, or unformatted.

Year = Optional, 4 character tax year, accepts an array of integers.

Email = Optional, 65 character string representing the recipients email address.

Account = Optional, 25 character string representing the recipients account number.

AlternateAccount = Optional, 40 character string that searches both forms and transactions AltRcpAccount number.  Returns the form if it or any of its transactions have a matching AltRcpAccount.

pCode = Optional, Payer Code filter that accepts an array of strings.  Default is to returns all Payer Codes.  If Payer Code Security is enabled in the web.config, the returned PCODEs will be limited to the ones configured for that API key.

FormStatus = Optional, form statuses to return, accepts an array of integers. The default returns all printed status forms. If an original 1099 form has a correction, only the latest correction is returned (Unless IncludeOriginal is set to true). This includes both parts of a 2 part correction, the zero correction and the new part. The original or new corrected values can be request and both parts are returned. Corrected W-2’s will return the latest correction (W-2C) plus any superseded corrections and the original.

Original RecordsCorrection Zero Form (2-Part)Correction (1-Part) / New Form (2-Part)

0: Original Pending
1: Original Printed
2: Original Printed and Voided
3: Original Printed and Filed Paper
4: Original Printed and e-Filed
5: Original SB Printed
6: Original Not Printed and e-Filed
7: Original Not Printed and SB e-Filed
8: Original SB Printed and SB e-Filed 

10: Corrected Pending
11: Corrected Printed
12: Corrected Printed and Voided
13: Corrected Printed and Filed Paper
14: Corrected Printed and e-Filed
15: Corrected SB Printed
16: Corrected Not Printed and e-Filed
17: Corrected Not Printed and SB e-Filed
18: Corrected SB Printed and SB e-Filed 
20: Correction Pending
21: Correction Printed
22: Correction Printed and Voided
23: Correction Printed and Filed Paper
24: Correction Printed and e-Filed
25: Correction SB Printed
26: Correction Not Printed and e-Filed
27: Correction Not Printed and SB e-Filed
28: Correction SB Printed and SB e-Filed 
Special Status Codes - 105: Zero Dropped, 107: Superseded Correction, 108: Deleted, 109: Negative/Invalid. 255: Placeholder/Abandoned

- IncludeOriginal = Optional, when set to true corrected 1099 forms will also return the original form in the response list.

FormType = Optional, if not passed all form types are returned.  Accepts an array of strings and can be any of the following:  1042-S, 1095-B, 1095-C, 1097-BTC, 1098, 1098-C, 1098-E, 1098-T, 1099-A, 1099-B, 1099-C, 1099-CAP, 1099-DIV, 1099-G, 1099-H, 1099-INT, 1099-K, 1099-LTC, 1099-MISC, 1099-OID, 1099-PATR, 1099-Q, 1099-R, 1099-S, 1099-SA, 3921, 3922, 5498, 5498-ESA, 5498-SA, W-2, W-2G.

TinMasking = Optional, enables TIN masking (XXX-XX-1234 / XX-XXX1234 / XXXXX1234) for TINs on approved forms types. Available options: “Mask” = Mask all, “NoMask” = No masking, “FilerDetermined” = User filer default setting. Default is no masking.

ShowDoNotPrint = Optional, allows forms marked as “Do Not Print” to be returned.

  • True = Returns all forms regardless of "Do Not Print" indicator on tax record.
  • False = Default option if not present.  Excludes any tax record that has the "Do Not Print" indicator checked.

Printed = Optional, Default returns forms that have been printed.

    • All = Optional, returns all forms regardless of DatePrinted field value.
    • Yes[Default] = Optional, returns all forms that have a DatePrinted field value != 0
    • No = Optional, returns all forms that have a DatePrinted field value = 0

 FormSpecificOptions = Optional, applies to a specific form types only, see below.

    • Form1099SABox3Code = Optional, integer code that returns forms 1099-SA with the specified box 3 distribution code only.  Valid codes are 1, 2, 3, 4, 5, and 6.
    • Form1099KFilterByFederalFilingThreshold = Optional, boolean code to only return forms 1099-K that meet the federal threshold of Box 1 > $20,000.00 AND Box 3 > 200.

+ Web service XML response modifier, optional.

          • SuppressTin = Optional, boolean code to suppress the TIN from being included in the response XML. Default is false/0, include TIN in response.

RequestForms Example

<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">

  <soap12:Body>
    <RequestForms xmlns="http://www.1099pro.com/webpresentment/api/v1">
      <request>
        <Tin>144-22-1027</Tin>
        <Year>
          <int>2012</int>
          <int>2011</int>
        </Year>
        <Email>test@1099pro.com</Email>
        <Account>AccNum</Account>
        <AlternateAccount>AltRcpAccount</AlternateAccount>
        <pCode>
          <string>TESTPAYER</string>
          <string>W2PAYER</string>
        </pCode>
        <FormStatus>
          <int>0</int>
          <int>1</int>
        </FormStatus>
        <FormType>
          <string>1099-MISC</string>
          <string>1099-INT</string>
        </FormType>
        <TinMasking>Mask</TinMasking>
        <
ShowDoNotPrint>0</ShowDoNotPrint>
        <Printed>All</Printed>

        <Password>password</Password>
        <Expiration>1</Expiration>
        <FormSpecificOptions>
          <Form1099SABox3Code>0</Form1099SABox3Code>
          <Form1099KFilterByFederalFilingThreshold>1</Form1099KFilterByFederalFilingThreshold>
        </FormSpecificOptions>
        <ApiKey>CGc65pCQ4DMUXllAO6pU</ApiKey>
        <PrivateKey>1idCGPUjWTEibm8yPcrf</PrivateKey>
        <Signature>jDObuWOaArANLscV8mn5ZNt9dHbpFh7z8xR2Basq==</Signature>
        <SuppressTin>0</SuppressTin>
      </request>
    </RequestForms>
  </soap12:Body>
</soap12:Envelope>

 

RequestXml Example

 

<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">

  <soap12:Body>
    <RequestXml xmlns="http://www.1099pro.com/webpresentment/api/v1">
      <request>
        <Tin>144-22-1027</Tin>
        <Year>
          <int>2012</int>
          <int>2011</int>
        </Year>
        <Email>test@1099pro.com</Email>
        <Account>AccNum</Account>
        <AlternateAccount>AltRcpAccount</AlternateAccount>
        <pCode>
          <string>TESTPAYER</string>
          <string>W2PAYER</string>
        </pCode>
        <FormStatus>
          <int>0</int>
          <int>1</int>
        </FormStatus>
        <FormType>
          <string>1099-MISC</string>
          <string>1099-INT</string>
        </FormType>
        <TinMasking>Mask</TinMasking>
        <ShowDoNotPrint>0</ShowDoNotPrint>
        <Printed>All</Printed>

        <Password>password</Password>
        <Expiration>1</Expiration>
        <FormSpecificOptions>
          <Form1099SABox3Code>0</Form1099SABox3Code>
          <Form1099KFilterByFederalFilingThreshold>1</Form1099KFilterByFederalFilingThreshold>
        </FormSpecificOptions>
        <ApiKey>CGc65pCQ4DMUXllAO6pU</ApiKey>
        <PrivateKey>1idCGPUjWTEibm8yPcrf</PrivateKey>
        <Signature>jDObuWOaArANLscV8mn5ZNt9dHbpFh7z8xR2Basq==</Signature>
        <SuppressTin>0</SuppressTin>
      </request>
    </RequestXml>
  </soap12:Body>
</soap12:Envelope>

Response XML Parameters

RequestForms Array of <FormsListItem>

Tin = String, recipients unformatted TIN.
Lastname = String, recipients last name/company.
Firstname = String, recipients first name.
FormType = String, forms form type.
Year = Integer, forms tax tear.
Printed = Boolean, was the form printed.
Correction = Boolean, does the form have an ‘X’ in the corrected box.
FormStatus = Integer, the forms status code.
PCode = String, the forms/filer pcode.
FilerName1 = String, the filers name line 1.
FilerName2 = String, the filers name line 2.
AlternateAccount = String, the form’s alternate account.
Account = String, the forms account.
TaxState = String, forms 2 character tax state code.
DateCreated = DateTime, of when the form was originally created in 1099 Pro.
DateLastEdit = DateTime, of when the form last edited in 1099 Pro.
Key = String, the PDF key used to retrieve the actual PDF form.

Response Example for RequestForms 

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <soap:Body>
 
 <RequestFormsResponse xmlns="http://www.1099pro.com/webpresentment/api/v1">
    <RequestFormsResult>
        <Errors />
        <Meta>
          <KeyValue>
            <Key>elapsed</Key>
            <Value>0.0093195</Value>
          </KeyValue>
        </Meta>
        <Items>
          <FormsListItem>
            <Tin>144221027</Tin>
            <Lastname>OSAKI</Lastname>
            <Firstname>JAMES</Firstname>
            <FormType>1099-MISC</FormType>
            <Year>2012</Year>
            <Printed>false</Printed>
            <Correction>false</Correction>
            <FormStatus>0</FormStatus>
            <PCode>TESTPAYER</PCode>
            <FilerName1>Export Test</FilerName1>
            <FilerName2 />
            <AlternateAccount />
            <Account />
            <TaxState>CA</TaxState>
            <DateCreated>2012-11-27T00:00:00</DateCreated>
            <DateLastEdit>2012-11-27T00:00:00</DateLastEdit>
            <Key>13559FB50C6D77B1471D0316FDFDFSG3453455DFE45D5B510E8E7474F4E380G84FInCAupdtT9cpqmgexCw==</Key>
          </FormsListItem>
        </Items>
      </RequestFormsResult>
    </RequestFormsResponse>
  </soap:Body>
</soap:Envelope>

 

RequestXml Array of <FormField>

 

FormField = String, Name of Field on the request Form(s)
Value = String, Value of FormField

 

Response Example for RequestXml

 

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <soap:Body>
  
 <RequestXmlResponse xmlns="http://www.1099pro.com/webpresentment/api/v1">
    <RequestXmlResult>
        <Errors />
        <Meta />
        <Forms>
          <Form>
            <Fields>
              <FormField name="TrackingID">
                <Value xsi:type="xsd:string">14</Value>
              </FormField>
              <FormField name="TaxYear">
                <Value xsi:type="xsd:string">2014</Value>
              </FormField>
              <FormField name="FormType">
                <Value xsi:type="xsd:string">1099MISC</Value>
              </FormField>
              <FormField name="PCode">
                <Value xsi:type="xsd:string">TestFiler</Value>
              </FormField>
              <FormField name="Category">
                <Value xsi:type="xsd:string" />
              </FormField>
              <FormField name="Source">
                <Value xsi:type="xsd:string">14</Value>
              </FormField>
              <FormField name="Recipient TIN">
                <Value xsi:type="xsd:string">144221027</Value>
              </FormField>
              <FormField name="Corrected">
                <Value xsi:type="xsd:string">14</Value>
              </FormField>
              <FormField name="Last Name/Company">
                <Value xsi:type="xsd:string">Osaki</Value>
              </FormField>
              <FormField name="First Name">
                <Value xsi:type="xsd:string">JAMES</Value>
              </FormField>
              .
              .  etc
              .

          </Fields>
        </Form>
      </Forms>
     </RequestXmlResult>
    </RequestXmlResponse>
  </soap:Body>
</soap:Envelope>


RequestPdf

Request XML Parameters 

Key = Required, the PDF key returned from the RequestForms search.

 

Request Example

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 
  <soap:Body>
    <RequestPdf xmlns="http://www.1099pro.com/webpresentment/api/v1"> 
      <request>
        <Key>13559FB50C6D77B1471D0316FDFDFSG3453455DFE45D5B510E8E795482B474F4E380G84FInCAupdtT9cpqmgexCw==</Key 
      </request>
    </RequestPdf>
  </soap:Body>
</soap:Envelope>

Response XML Parameters

FileData = The base64 encoded binary stream of the PDF.  Usually passed back to the client as a download.  

Filename = A string containing the file name of the PDF file.


Response Example

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap=
http://schemas.xmlsoap.org/soap/envelope/>
  <soap:Body>
    <RequestPdfResponse xmlns="http://www.1099pro.com/webpresentment/api/v1">
      <RequestPdfResult>
        <FileData>1C362C5912771AF512B932DBED3198A172A5E658437E9E447697D09B80525B571576107D...</FileData>
        <Filename>2012-1099MISC.pdf</Filename>
      </RequestPdfResult>
    </RequestPdfResponse>
  </soap:Body>
</soap:Envelope>

pdf.aspx?key=[PDF Key] - Used instead of “RequestPdf” to provide a direct download link to the PDF.



Optional HMAC Signature Process:

HMAC or hash-based message authentication code is used to simultaneously verify both the data integrity and the authenticity of the request. We develop our HMAC signature using the HMAC SHA-256 hashing algorithm. The secret key component is stored in the API’s web.config <add key="1099ProHmacKey" value="xxx" /> value attribute. The "1099ProHmacKey" is a 512-bit base64 encoded secret key.  We develop the signed HMAC message in the following way:


Tin<CrLf>
Account<CrLf>
AlternateAccount<CrLf>
Email<CrLf>
Timestamp<CrLf>
FormStatus<CrLf>
2nd FormStatus...<CrLf>
FormType<CrLf>
2nd FormType…<CrLf>
Password<CrLf>
PCode<CrLf>
2nd Pcode…<CrLf>
Year<CrLf>
2nd Year…<CrLf>


Each parameter that you actually use is placed on a line in the order shown above. If you don’t use a parameter then it is not added.  Timestamp is in UTC in the following format "10/29/2019 4:09:02 PM".


HMAC Example/Test Case:

HMAC Secret Key = a7NJyW5gTHl3YH9xkKgeL4uvovng7uMAS97lfYcf2eOskJuqqF45g19xwYOnIAOWfPmXvCIirEBAnKpBLYfZng==

Example of a HMAC signed XML Request:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soap:Body>
      <RequestForms xmlns="http://www.1099pro.com/webpresentment/api/v1">
         <request>
            <Tin>130000013</Tin>
            <Year>
               <int>2018</int>
               <int>2017</int>
            </Year>
            <Account>1234abc</Account>
            <pCode>
               <string>FILER2</string>
            </pCode>
            <FormStatus>
               <int>0</int>
               <int>1</int>
            </FormStatus>
            <FormType>
               <string>1099-MISC</string>
               <string>1099-INT</string>
            </FormType>
            <Timestamp>10/28/2019 11:17:25 PM</Timestamp>
            <ApiKey>ApiKey3</ApiKey>
            <PrivateKey>fVrcdiN28dfQTwRhg/O2qw6fkEaf3h3UO8ChdSjJ</PrivateKey>
            <Signature>DiO2FXtFZNz/nqJsScWCG2KL0YwUOyw729lu/LjDdZw=</Signature>
         </request>
      </RequestForms>
   </soap:Body>
</soap:Envelope>

HMAC Message Developed From Request Parameters:

130000013
1234abc
10/28/2019 11:17:25 PM
0
1
1099-MISC
1099-INT
FILER2
2018
2017

Calculated HMAC Signature = DiO2FXtFZNz/nqJsScWCG2KL0YwUOyw729lu/LjDdZw=

        You can use our tools site to test the generation of your HMAC signature: https://tools.1099pro.com/hmac/

Sample C# Console Application to Generate HMAC Signature
using System;
using System.Text;
using System.Security.Cryptography;

namespace HMAC
{
    class Program
    {
        static void Main(string[] args)
        {
            //Request XML Parameters
            var Tin = "130000013";
            var Account = "1234abc";
            var AlternateAccount = "";
            var Email = "";
            var Timestamp = DateTime.UtcNow.ToString(); // In UTC "10/28/2019 11:17:25 PM" format
            var FormStatus = new[] { 0, 1 };
            var FormType = new[] { "1099-MISC", "1099-INT" };
            var Password = "";
            var pCode = new[] { "FILER2" };
            var Year = new[] { "2018", "2017" };

            //Build HMAC Message from Request XML Parameters in the following order
            StringBuilder HmacMessage = new StringBuilder();
            if (!string.IsNullOrWhiteSpace(Tin)) HmacMessage.AppendLine(Tin);  //TIN
            if (!string.IsNullOrWhiteSpace(Account)) HmacMessage.AppendLine(Account);  //Account
            if (!string.IsNullOrWhiteSpace(AlternateAccount)) HmacMessage.AppendLine(AlternateAccount);  //Alternate Account
            if (!string.IsNullOrWhiteSpace(Email)) HmacMessage.AppendLine(Email); // Email
            if (!string.IsNullOrWhiteSpace(Timestamp)) HmacMessage.AppendLine(Timestamp); //Timestamp
            if (FormStatus != null) //Form Status
            {
                foreach (var status in FormStatus)
                {
                    HmacMessage.Append(status);
                    HmacMessage.AppendLine();
                }
            }
            if (FormType != null) //Form Types
            {
                foreach (var type in FormType)
                {
                    if (!string.IsNullOrWhiteSpace(type))
                    {
                        HmacMessage.Append(type);
                        HmacMessage.AppendLine();
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(Password)) HmacMessage.AppendLine(Password); //PDF Password
            if (pCode != null) //Pcodes
            {
                foreach (var pcode in pCode)
                {
                    if (!string.IsNullOrWhiteSpace(pcode))
                    {
                        HmacMessage.Append(pcode);
                        HmacMessage.AppendLine();
                    }
                }
            }
            if (Year != null) //Tax Years
            {
                foreach (var year in Year)
                {
                    HmacMessage.Append(year);
                    HmacMessage.AppendLine();
                }
            }

            //Display HMAC Message
            Console.WriteLine("--HMAC Message--");
            Console.WriteLine(HmacMessage);

            //  --HMAC Message--
            //  130000013
            //  1234abc
            //  10/28/2019 11:17:25 PM
            //  0
            //  1
            //  1099-MISC
            //  1099-INT
            //  FILER2
            //  2018
            //  2017
            //

            //Convert HMAC Message to Bytes
            var encoding = new System.Text.ASCIIEncoding();
            byte[] HmacMessage_Bytes = encoding.GetBytes(HmacMessage.ToString());

            //Convert Base64 encoded HMAC secret key to bytes
            var HmacSecretKey_Base64 = "a7NJyW5gTHl3YH9xkKgeL4uvovng7uMAS97lfYcf2eOskJuqqF45g19xwYOnIAOWfPmXvCIirEBAnKpBLYfZng==";
            byte[] HmacSecretKey_Bytes = System.Convert.FromBase64String(HmacSecretKey_Base64);

            //Calculate HMAC Signature
            byte[] HmacSignature_Bytes;
            using (var HmacSHA256 = new HMACSHA256(HmacSecretKey_Bytes))
            {
                HmacSignature_Bytes = HmacSHA256.ComputeHash(HmacMessage_Bytes);
            }

            //Convert HMAC Signature to Base64 encoded string
            string HmacSignature_String = Convert.ToBase64String(HmacSignature_Bytes);

            //Display HMAC Signature
            Console.WriteLine("--HMAC Signature--");
            Console.WriteLine(HmacSignature_String);
            Console.ReadLine();

            //  --HMAC Signature--
            //  DiO2FXtFZNz/nqJsScWCG2KL0YwUOyw729lu/LjDdZw=
        }
    }
}
  • No labels