Create forms

Prepares the caller org's 1099 drafts for a tax year, as the PAYER: one 1099-NEC and/or 1099-MISC per payee whose reportable payments on Hanzo's rails reach the year's threshold, from the same derivation GET /v1/tax/payments answers.

POST /v1/tax/forms

Addresshttps://api.hanzo.ai/v1/tax/forms
MethodPOST
Operationpost_tax_forms
AuthAuthorization: Bearer $HANZO_API_KEY

Prepares the caller org's 1099 drafts for a tax year, as the PAYER: one 1099-NEC and/or 1099-MISC per payee whose reportable payments on Hanzo's rails reach the year's threshold, from the same derivation GET /v1/tax/payments answers. Org admins only.

Each draft carries the payee as its W-9 names it — under a live grant, and otherwise only its org id — its boxes, box 4, the due dates, the payments it sums, and backup withholding at 24% when the payer holds no TIN for the payee (IRC §3406(a)(1)(A)) — an uncertified W-9 is stated as a warning, not a withholding, because these payments do not require the certification. Preparing again refreshes a draft or reviewed form in place (a reviewed one goes back to draft, to be reviewed again); one payee has at most one live form per kind and year, so a second preparation racing the first is refused, never doubled. A form already furnished is left alone and named in skipped — change it by correcting it. Nothing is furnished to anyone and nothing is filed with the IRS.

Request

1 field, body application/json (required).

FieldInTypeRequiredDescription
yearbodyinteger (int64)—Year is the calendar year the payments were made in.

Response

StatusBodyMeaning
200tax.Preparedok
defaultproblem-detailsrefused

200 body — 61 fields.

FieldInTypeAlwaysDescription
formsbodytax.Form[]—Forms are the drafts made or refreshed.
forms[].accountbodystring—Account is the account number the form prints — the original form's id, which a correction keeps, so the IRS can tie the two.
forms[].backupbodytax.Withholding—
forms[].backup.dueCentsbodyinteger (int64)—DueCents is what 24% of the reported boxes comes to — what should have been withheld.
forms[].backup.ratebodyinteger (int64)—Rate is the backup withholding rate, in percent: 24.
forms[].backup.reasonbodystring—Reason says why, and which rule — or, when nothing is required, what the payer should still know.
forms[].backup.requiredbodyboolean—Required is true when the payer holds no TIN for the payee — the IRC §3406(a)(1)(A) trigger these forms can know.
forms[].boxesbodytax.Amount[]—Boxes are the figures, box 4 (federal income tax withheld) included.
forms[].boxes[].boxbodystring—Box is the box number, e.g. "1a".
forms[].boxes[].centsbodyinteger (int64)—Cents is the amount in cents.
forms[].boxes[].labelbodystring—Label is the box's caption on the form.
forms[].certifiedbodyboolean—Certified is whether the payee's W-9 was certified when the form was prepared.
forms[].correctedbodyboolean—Corrected is true for a form that corrects one already furnished.
forms[].createdAtbodyinteger (int64)—CreatedAt is when the form was prepared, unix seconds.
forms[].deliverybodystring—Delivery is electronic (Copy B in the payee's inbox) or paper, once furnished.
forms[].duebodytax.Deadline—
forms[].due.filebodystring—File is the date the return is due to the IRS, electronically (IRIS).
forms[].due.furnishbodystring—Furnish is the date Copy B is due to the recipient.
forms[].furnishedAtbodyinteger (int64)—FurnishedAt is when Copy B was delivered in the inbox, or marked owed on paper.
forms[].idbodystring—ID is the form's id, "f1099_"-prefixed.
forms[].kindbodystring—Kind is 1099-NEC or 1099-MISC.
forms[].mailedAtbodyinteger (int64)—MailedAt is when the payer recorded mailing a paper Copy B.
forms[].notesbodystring[]—Notes are what still needs a person, in words.
forms[].payerbodytax.Party—
forms[].payer.addressbodytax.Address—
forms[].payer.address.citybodystring—City is the city or town.
forms[].payer.address.countrybodystring—Country is ISO 3166-1 alpha-2; "US" when absent.
forms[].payer.address.line1bodystring—Line1 is the number, street, and apartment or suite.
forms[].payer.address.line2bodystring—Line2 continues the street address, when there is more of it.
forms[].payer.address.statebodystring—State is the two-letter state or territory code.
forms[].payer.address.zipbodystring—ZIP is five or nine digits.
forms[].payer.businessNamebodystring—BusinessName is W-9 line 2, when there is one.
forms[].payer.namebodystring—Name is W-9 line 1.
forms[].payer.orgbodystring—Org is the Hanzo org.
forms[].payer.phonebodystring—Phone is the payer's telephone number; a recipient has none on the form.
forms[].payer.tinbodystring—TIN is masked here always.
forms[].payer.tinTypebodystring—TINType is ssn or ein; empty when no TIN is held.
forms[].paymentsbodystring[]—Payments are the rail payment ids summed into the boxes.
forms[].reasonbodystring—Reason is why a corrected form was made.
forms[].recipientbodytax.Party—
forms[].recipient.addressbodytax.Address—
forms[].recipient.address.citybodystring—City is the city or town.
forms[].recipient.address.countrybodystring—Country is ISO 3166-1 alpha-2; "US" when absent.
forms[].recipient.address.line1bodystring—Line1 is the number, street, and apartment or suite.
forms[].recipient.address.line2bodystring—Line2 continues the street address, when there is more of it.
forms[].recipient.address.statebodystring—State is the two-letter state or territory code.
forms[].recipient.address.zipbodystring—ZIP is five or nine digits.
forms[].recipient.businessNamebodystring—BusinessName is W-9 line 2, when there is one.
forms[].recipient.namebodystring—Name is W-9 line 1.
forms[].recipient.orgbodystring—Org is the Hanzo org.
forms[].recipient.phonebodystring—Phone is the payer's telephone number; a recipient has none on the form.
forms[].recipient.tinbodystring—TIN is masked here always.
forms[].recipient.tinTypebodystring—TINType is ssn or ein; empty when no TIN is held.
forms[].statusbodystring—Status is draft, reviewed, furnished, owed or void.
forms[].supersededBybodystring—SupersededBy is the form that corrects this one, once there is one.
forms[].supersedesbodystring—Supersedes is the form this one corrects.
forms[].updatedAtbodyinteger (int64)—UpdatedAt is when its status last moved, unix seconds.
forms[].w9bodystring—W9 is where the payer's W-9 request stood when the form was prepared.
forms[].yearbodyinteger (int64)—Year is the calendar year the payments were made.
skippedbodystring[]—Skipped says, per payee and form, why nothing was prepared — a form already furnished is never re-prepared, only corrected.
yearbodyinteger (int64)—Year is the tax year.

Failure carries the platform error shape — see Errors.

Examples

hanzo has no subcommand for this operation — the CLI serves only what cloud's live route table confirms. Use HTTP or an SDK.

import { Configuration, TaxApi } from 'hanzoai';

const api = new TaxApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postTaxForms({ year: 0 });
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import TaxApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = TaxApi(client).post_tax_forms(year=0)
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.TaxAPI.PostTaxForms(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, tax_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = tax_api::post_tax_forms(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.TaxApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new TaxApi(client).postTaxForms();
curl -X POST https://api.hanzo.ai/v1/tax/forms \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "year": 0
     }'

MCP reaches tax through the tax tool, which names its 26 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_tax_filings"
         }
       }
     }'

Tax API · All Hanzo APIs · Interactive reference

Was this page useful?