Migration Guide from v3 to v4

Abound's v4 API makes significant advancements in 1099 compliance automation and converts on feedback from customers across payments, staffing, lending and banking sectors. Here is a quick summary of what you can expect in v4:

  • transitioned to being 100% stateless
  • userId association is now optional throughout the entire API
  • multi-entity support
  • more transparent and granular resource statuses
  • improved developer experience
  • linked paper trails for corrected and voided 1099 forms
  • improved pdf formatting and rendering
  • introduction of tinFingerprints
  • added support for foreign addresses
  • comprehensive filtering options of list operations (e.g. filter by payerTin or payeeTin)
  • increased webhook rigidity
  • simplified pagination for LIST operations

Read below to learn how to make the jump from v3 to v4:

πŸ“˜

Want to speak with a solutions engineer?

v3 is officially deprecated and will be completely removed on April 1, 2024. We encourage you to reach out to [email protected] and book time with a solutions engineer to discuss your company's plan to upgrade.


API endpoint changes

Removed

  • /payers (For more context, read the "Move to stateless" section below)

Changed

  • /users/{userId}/documents with a form type passed in the body is now:
    • /documents/1099-nec
    • /documents/1099-k
    • /documents/1099-int
    • /documents/w-9
  • accessTokens has been renamed to access-tokens

New

  • /tin-verifications

Best practice updates

  • All dollar amounts are now strictly in cents
  • PUT calls operate as the spec indicates dropping fields that are not included in the body
  • The filing year field, year, has been renamed to filingYear
  • ISO 1601 timestamps are now used instead of UNIX timestamps
  • Response payloads now contain the response data at the root level (not nested under a data object) while supplement data like the Abound-Request-LogId, Abound-Request-Timestamp have been hoisted into the headers
  • All 400 data validation errors will come back at once in an array of errors
  • TINs are returned in their masked format paired with a tinFingerprint (Read more on fingerprints here)
  • Pagination has been simplified. Read more here.

Move to stateless

Given the stateless nature of the v4 API, ID pointers that hydrate request bodies are no longer used and instead full-context, inline payloads are required.


Old way

In v3 when filing a 1099-NEC the path contained a pointer to the userId which indirectly injected the payee's information (i.e. address, tin, etc.) into the request:

https://sandbox-api.withabound.com/v3/users/<<testUserId>>/documents

Further, the request body contained a pointer to the payerId which indirectly injected the payer's information (i.e. address, tin, payerPhonenumber, etc.) into the request:

{
  "type": "1099nec",
  "year": 2023,
  "payerId": "<<testPayerId>>",
  "isCorrected": false,
  "accountNumber": "1234567890",
  "nonemployeeCompensation": 234.23,
  "hasDirectSalesOver5000": false,
  "federalIncomeTaxWithheld": 0,
  "stateTaxInfo": [
    {
      "stateTaxWithheld": 0,
      "filingState": "CA",
      "payerStateId": "1234567891",
      "stateIncome": 3455.43
    }
  ]
}

New way

In v4 ID pointers to hydrate the requests are NOT used and the entire request context is required to be passed into the request body:

https://sandbox-api.withabound.com/v4/documents/1099-nec
{
  "filingYear": 2023,
  "payer": {
    "name": "Hooli",
    "tin": "111111111",
    "address": "1401 N Shoreline Blvd",
    "address2": "Suite 1",
    "city": "Mountain View",
    "state": "CA",
    "postalCode": "94043",
    "country": "US",
    "phoneNumber": "6501014096",
  },
  "payee": {
    "name": "Ada Lovelace",
    "tin": "000000000",
    "address": "256 Byron Street",
    "address2": "Suite 32",
    "city": "Palo Alto",
    "state": "CA",
    "postalCode": "94306",
    "country": "US"
  },
  "formFields": {
    "accountNumber": "1234567890",
    "nonemployeeCompensation": 23423,
    "hasDirectSalesOver5000": false,
    "federalIncomeTaxWithheld": 0,
    "stateTaxInfo": [
      {
        "stateTaxWithheld": 0,
        "filingState": "CA",
        "payerStateId": "1234567891",
        "stateIncome": 345543
      }
    ]
  }
}

Given these changes, the v3/payer endpoint has been removed as it's no longer required. In addition, the profile and business object of the v3/user resource has been removed.


UserId is now optional

The user resource is a powerful organization tool (Read more here), but there may be times where it's unnecessary to use. In v4 we've made the userId optional in all requests.

Old way

In v3 the userId was found and required in almost every endpoint's path:

https://sandbox-api.withabound.com/v3/users/{userId}/documents

New Way

In v4 the path is simpler and you're able to filter by userId if desired:

https://sandbox-api.withabound.com/v4/documents?userId=userId_sampleXGMFnhOpeR

Tin Verification now have their own endpoint

In v3 the user resource would be used to verify the tin and name against the IRS' records. It was also limiting and complicated because the user could only have two entities connected to it at one time: one nested under the profile object and another nested under the business object.

In v4 the profile and business objects have been removed in favor of a new stateless tin-verifications endpoint.

Old way

curl \
  --request POST \
  --url https://sandbox-api.withabound.com/v3/users \
  --header 'Authorization: Bearer <<apiKey>>' \
  --data '{
    "user": {
      "profile": {
        "firstName": "Ada",
        "lastName": "Lovelace",
        "socialSecurityNumber": "123456789"
      },
      "business": {
        "name": "InGen Corporation",
        "ein": "123456789"
      }
    }
  }'

New way

curl \
  --request POST \
  --url https://sandbox-api.withabound.com/v4/tin-verifications \
  --header 'Authorization: Bearer <<apiKey_v4>>' \
  --data '{
    "name": "Hooli Inc.",
    "tin": "111111111",
    "userId": "<<testUserId_v4>>"
  }'

πŸ“˜

You can optionally pass the userId in the body

Note that in v4 you can still associate a tin verification with a user by passing the userId into the body.


Actions added to Form 1099s

In v3 when you created a Form 1099 it would generate the PDF and immediately file it with the federal and state governments.

Along with making everything stateless, v4 aslo breaks down the Form 1099 lifecycle into more granular steps which advance when you perform an "action" on the resource.


New Form 1099 Actions

  • Create (POST /documents/1099-*): validates the data and generates the PDF form
  • File (POST /documents/1099-*/file): kicks off the submission to the required government agencies
  • Mail (POST /documents/1099-*/mail): prints and mails the PDF form to the supplied address
  • Void (POST /documents/1099-*/void): generates a voided out document and instantly files it with the required government agencies
  • Correct (POST /documents/1099-*/correct): generates a new document with the corrected data, voids out the original filing (if neccessary), and instantly files all required documents with the required government agencies. Intelligently handles one-transaction and two-transaction corrections.

Read more about the webhooks associated with these actions here.


Webhook updates

In v4 you still register and validate webhooks the same way you did in v3. However, the payload on the webhook POST calls has changed. Please see information about these changes here.


SDKs

Node SDK

The latest Node SDK (v5.x) supports our v4 APIs. See SDKs or visit our GitHub for more information.

Java SDK

Our Java SDK does not have v4 support. Email us at [email protected] if this is a blocker for your company.