# BulkUpsert1099Forms

Create or update multiple 1099/1095/W2/1042S forms

`POST /1099/forms/$bulk-upsert`

**API:** Avalara 1099 & W-9 API Definition
**Tag:** Forms 1099
**API Version:** 2.0
**Base URL:** https://api.sbx.avalara.com/avalara1099
**Authentication:** Bearer token

Source: https://developer.avalara.com/products/avalara-1099-and-w9/api/methods/Forms%201099/BulkUpsert1099Forms/

## Description

This endpoint allows you to create or update multiple 1099/1095/W2/1042S forms.
Maximum of 5000 forms can be processed in a single bulk request.

**Date Scheduling Rules:**

If federalEfileDate, stateEfileDate, or recipientEdeliveryDate are between current date and beginning of blackout period, scheduled to that date.
If dates are in the past or blackout period, scheduled to next available date.
For blackout period information, see https://www.track1099.com/info/IRS_info.
StateEfileDate must be on or after federalEfileDate.
Set dates to null to leave unscheduled.

## Parameters

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `dryRun` | boolean | query | No | defaults to false. If true, it will NOT change the DB. It will just return a report of what would've have been changed in the DB |
| `avalara-version` | string | header | Yes | API version |
| `X-Correlation-Id` | string | header | No | Unique correlation Id in a GUID format |
| `X-Avalara-Client` | string | header | No | Identifies the software you are using to call this API. For more information on the client header, see [Client Headers](https://developer.avalara.com/avatax/client-headers/) . |

## Request Body

**Content-Type:** `application/json`

**Content-Type:** `text/json`

**Content-Type:** `application/*+json`

## Responses

| Status | Description | Schema |
|---|---|---|
| 200 | Success | `JobResponse` |
| 400 | Bad Request | `ErrorResponse` |
| 401 | Unauthorized |  |
| 404 | Not Found | `ErrorResponse` |
| 500 | Server Error | `ErrorResponse` |

### 200 Response: `JobResponse`

Response model for job operations

| Property | Type | Required | Description |
|---|---|---|---|
| `id` | string | No | Unique identifier for the job |
| `type` | string | No | Job type identifier. Will always be "update_job" for bulk upsert operations |
| `status` | string | No | Current status of the job (e.g., Success, Failed, InProgress) Values: `InProgress`, `Success`, `Failed`. |
| `errorMessage` | string | No | Error message if the job failed, null otherwise |
| `totalProcessed` | integer | No | Total number of forms processed. Value can be 0 or another value based on what the job has available |
| `totalRows` | integer | No | Total number of forms in the request. Value can be 0 or another value based on what the job has available |
| `updatedValid` | integer | No | Number of forms updated and valid for e-filing and e-delivery. Value can be 0 or another value based on what the job has available |
| `updatedNoEmail` | integer | No | Number of forms updated and valid for e-filing but missing email or email is undeliverable. Value can be 0 or another value based on what the job has available |
| `updatedInvalid` | integer | No | Number of forms updated but invalid for e-filing. Value can be 0 or another value based on what the job has available |
| `skippedDuplicate` | integer | No | Number of forms skipped because they would have updated a record already updated once in the request. Value can be 0 or another value based on what the job has available |
| `skippedInvalid` | integer | No | Number of forms skipped because they would have made a form invalid and the form is already e-filed or scheduled for e-filing, or because you do not have permission to update forms that have been scheduled. Value can be 0 or another value based on what the job has available |
| `skippedMultipleMatches` | integer | No | Number of forms skipped because they matched multiple forms. Value can be 0 or another value based on what the job has available |
| `notFound` | integer | No | Number of forms skipped because no matching form or issuer could be found. Value can be 0 or another value based on what the job has available |
| `createdInvalid` | integer | No | Number of new forms created because no matching form could be found (and `upsert` was true) - with errors. Value can be 0 or another value based on what the job has available |
| `createdNoEmail` | integer | No | Number of new forms created because no matching form could be found (and `upsert` was true) - valid for e-filing but missing email or email is undeliverable. Value can be 0 or another value based on what the job has available |
| `createdValid` | integer | No | Number of new forms created because no matching form could be found (and `upsert` was true) - valid for e-filing and e-delivery. Value can be 0 or another value based on what the job has available |
| `dryRun` | boolean | No | Dry run. If `true`, this job only simulates the changes but doesn't actually persist them. |
| `upsert` | boolean | No | Upsert. If `true`, this job will first attempt to update existing records if matches can be found. Matches are done in the following order: Form ID, Form Reference ID and tax year, Form TIN and tax year. |
| `link` | string | No | Link to access the job details |
| `processedForms` | object[] | No | List of processed forms returned when bulk-upsert processes ≤1000 records. Same format as GET /1099/forms response. Only available in bulk-upsert endpoint responses. |

## Example Request

```bash
curl -X POST "https://api.sbx.avalara.com/avalara1099/1099/forms/$bulk-upsert" \
  -H "Authorization: Basic <credentials>" \
  -H "Accept: application/json"
```