# ScanForm

A `ScanForm` can be created to speed up and simplify the carrier pickup process.
The `ScanForm` is one document that can be scanned to mark all included tracking codes as "Accepted for Shipment" by the carrier.

The following criteria must met before creation:

- Refunded `Shipments` cannot be added.
- Each `Shipment` must have the same `origin_address`.
- Each `Shipment` must be dated (using the `label_date` option) on or after the date the form is generated.
- All `Shipments` must belong to the same carrier account.
- Any given `Shipment` cannot be added to more than one `ScanForm`.
- Existing `ScanForms` may not be updated with additional `Shipments`.
  If a `ScanForm` already exists and new `Shipments` need to be added, a new `ScanForm` must be created.
- `Shipments` should be provided in the form of an array.

---

## ScanForm object

| Property | Type | Description |
|----------|------|-------------|
| id | string | Unique, begins with "sf_" |
| object | string | "ScanForm" |
| message | string | Human readable message explaining any failures |
| address | Address | Address that the packages will be shipped from |
| tracking_codes | string array | Tracking codes included on the ScanForm |
| form_url | string | Url of the document |
| form_file_type | string | File format of the document |
| batch_id | string | The ID of the associated Batch. Unique, starts with "batch_". |
| created_at | datetime | When the ScanForm was created |
| updated_at | datetime | When the ScanForm was last updated |

Example Object:

```json
{
  "id": "sf_244b6b0b1487472db12dcdfb2622ec8d",
  "object": "ScanForm",
  "created_at": "2025-05-09T20:40:04Z",
  "updated_at": "2025-05-09T20:40:04Z",
  "tracking_codes": ["9405500208303109884151"],
  "address": {
    "id": "adr_c8c8ddad2d1511f0b56e3cecef1b359e",
    "object": "Address",
    "created_at": "2025-05-09T20:40:03+00:00",
    "updated_at": "2025-05-09T20:40:03+00:00",
    "name": "EasyPost",
    "company": null,
    "street1": "417 Montgomery Street",
    "street2": "5th Floor",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94104",
    "country": "US",
    "phone": "4153334445",
    "email": "support@easypost.com",
    "mode": "test",
    "carrier_facility": null,
    "residential": null,
    "federal_tax_id": null,
    "state_tax_id": null,
    "verifications": {}
  },
  "status": "created",
  "message": null,
  "form_url": "https://easypost-files.s3.us-west-2.amazonaws.com/files/scan_form/20250509/e8edaa9a23e2044386ae61411cf7227014.pdf",
  "form_file_type": null,
  "batch_id": "batch_b35046236c8c4740accf6ed173b64964",
  "confirmation": null
}
```

---

## Create a ScanForm

### Example: POST /scan_forms

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/scan_forms \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "shipments": [
      {
        "id": "shp_..."
      },
      {
        "id": "shp_..."
      }
    ]
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func create() {
	client := easypost.New("EASYPOST_API_KEY")

	scanForm, _ := client.CreateScanForm("shp_...", "shp_...")

	fmt.Println(scanForm)
}
```

#### Java

```java
package shipments;

import com.easypost.exception.EasyPostException;
import com.easypost.model.ScanForm;
import com.easypost.model.Shipment;
import com.easypost.service.EasyPostClient;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Create {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        Shipment shipment = client.shipment.retrieve("shp_...");

        List<Shipment> shipments = new ArrayList<Shipment>();
        shipments.add(shipment);

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("shipments", shipments);

        ScanForm scanForm = client.scanform.create(params);

        System.out.println(scanForm);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.Shipment shipment = await client.Shipment.Retrieve("shp_...");

            EasyPost.Parameters.ScanForm.Create parameters = new()
            {
                Shipments = new List<EasyPost.Parameters.IShipmentParameter>
                {
                    shipment
                }
            };

            EasyPost.Models.API.ScanForm scanForm = await client.ScanForm.Create(parameters);

            Console.WriteLine(JsonConvert.SerializeObject(scanForm, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const scanForm = await client.ScanForm.create({
    shipments: [{ id: 'shp_...' }, { id: 'shp_...' }],
  });

  console.log(scanForm);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$scanForm = $client->scanForm->create([
    'shipments' => [
        ['id' => 'shp_...'],
        ['id' => 'shp_...'],
    ]
]);

echo $scanForm;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

scan_form = client.scan_form.create(
    shipments=[
        {"id": "shp_..."},
        {"id": "shp_..."},
    ]
)

print(scan_form)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

scan_form = client.scan_form.create(
  shipments: [
    {
      id: 'shp_...',
    },
    {
      id: 'shp_...',
    },
  ],
)

puts scan_form
```

A `ScanForm` can be created in two ways:

- Create a `ScanForm` for `Shipments` directly
- Create a `ScanForm` for a `Batch` of `Shipments`

> Note: A `ScanForm` can only include shipments from one carrier account. Shipments from different carrier accounts
  require separate `ScanForms`.

> Note: A `Batch` is created in the background for
  `Shipments` as an intermediate process to creating `ScanForms`. A `ScanForm` can
  be created for one or more `Shipments`. It is recommended to **keep each batch
  under 1,000 shipments**. This best practice helps avoid timeout errors during the batch buying process.

[Note: This object is immutable after creation. Review the rendered documentation for details.]

---

## Retrieve all ScanForms

### Example: GET /scan_forms

#### cURL

```shell
curl -X GET "https://api.easypost.com/v2/scan_forms?page_size=5" \
  -u "EASYPOST_API_KEY":
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func list() {
	client := easypost.New("EASYPOST_API_KEY")

	scanForms, _ := client.ListScanForms(
		&easypost.ListOptions{
			PageSize: 5,
		},
	)

	fmt.Println(scanForms)
}
```

#### Java

```java
package shipments;

import com.easypost.exception.EasyPostException;
import com.easypost.model.ScanFormCollection;
import com.easypost.service.EasyPostClient;

import java.util.HashMap;

public class All {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("page_size", 5);

        ScanFormCollection scanForms = client.scanform.all(params);

        System.out.println(scanForms);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Parameters.ScanForm.All parameters = new()
            {
                PageSize = 5
            };

            EasyPost.Models.API.ScanFormCollection scanFormCollection = await client.ScanForm.All(parameters);

            Console.WriteLine(JsonConvert.SerializeObject(scanFormCollection, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const scanForms = await client.ScanForm.all({
    page_size: 5,
  });

  console.log(scanForms);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$scanForms = $client->scanForm->all([
    'page_size' => 5
]);

echo $scanForms;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

scan_forms = client.scan_form.all(page_size=5)

print(scan_forms)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

scan_forms = client.scan_form.all(
  page_size: 5,
)

puts scan_forms
```

A list of all `ScanForm` objects associated with the given `API Key` can also be retrieved.
See the Pagination section of our docs for more details on retrieving all records when multiple pages are available.

---

## Retrieve a ScanForm

### Example: GET /scan_forms/:id

#### cURL

```shell
curl -X GET https://api.easypost.com/v2/scan_forms/sf_... \
  -u "EASYPOST_API_KEY":
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func retrieve() {
	client := easypost.New("EASYPOST_API_KEY")

	scanForm, _ := client.GetScanForm("sf_...")

	fmt.Println(scanForm)
}
```

#### Java

```java
package shipments;

import com.easypost.exception.EasyPostException;
import com.easypost.model.ScanForm;
import com.easypost.service.EasyPostClient;

public class Retrieve {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        ScanForm scanForm = client.scanform.retrieve("sf_...");

        System.out.println(scanForm);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.ScanForm scanForm = await client.ScanForm.Retrieve("sf_...");

            Console.WriteLine(JsonConvert.SerializeObject(scanForm, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const scanForm = await client.ScanForm.retrieve('sf_...');

  console.log(scanForm);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$scanForm = $client->scanForm->retrieve('sf_...');

echo $scanForm;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

scan_form = client.scan_form.retrieve("sf_...")

print(scan_form)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

scan_form = client.scan_form.retrieve('sf_...')

puts scan_form
```

Retrieve a `ScanForm` by its `id`.