> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.staple.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.staple.ai/_mcp/server.

# Scan Asynchronous Multiple Documents

POST https://api.staple.io/v2/documents/scan/async-documents
Content-Type: multipart/form-data

Scan a asynchronous document using the Invoice model in Staple to receive the document ID extracted. The Read operation executes asynchronously. The time for completion of the text extraction process depends on the volume of the text and the number of pages in the document. After the document finished scanning, you can get data extracted by document ID via [https://api-gateway.staple.io/v1/documents/{docId}](https://api-gateway.staple.io/v1/documents/%7BdocId%7D)

The documents would be left in the queue specified for any further manipulation.

If you are looking to scan a file for a custom model you have developed, simply create a queue using that model and use the queue ID with this endpoint. It will extract data based on your queue instead of the invoice model.

Reference: https://docs.staple.ai/api-reference/v2/documents/scan-asynchronous-multiple-documents

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: v2
  version: 1.0.0
paths:
  /v2/documents/scan/async-documents:
    post:
      operationId: scanAsynchronousMultipleDocuments
      summary: Scan Asynchronous Multiple Documents
      description: >-
        Scan a asynchronous document using the Invoice model in Staple to
        receive the document ID extracted. The Read operation executes
        asynchronously. The time for completion of the text extraction process
        depends on the volume of the text and the number of pages in the
        document. After the document finished scanning, you can get data
        extracted by document ID via
        [https://api-gateway.staple.io/v1/documents/{docId}](https://api-gateway.staple.io/v1/documents/%7BdocId%7D)


        The documents would be left in the queue specified for any further
        manipulation.


        If you are looking to scan a file for a custom model you have developed,
        simply create a queue using that model and use the queue ID with this
        endpoint. It will extract data based on your queue instead of the
        invoice model.
      tags:
        - documents
      parameters:
        - name: x-api-key
          in: header
          description: API key issued by Staple.
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Documents_scanAsynchronousMultipleDocuments_Response_200
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                files:
                  type: string
                  format: binary
                  description: File to upload
                qid:
                  type: string
                handwritten:
                  type: string
              required:
                - files
                - qid
                - handwritten
servers:
  - url: https://api.staple.io
    description: https://api.staple.io
components:
  schemas:
    Documents_scanAsynchronousMultipleDocuments_Response_200:
      type: object
      properties: {}
      description: Empty response body
      title: Documents_scanAsynchronousMultipleDocuments_Response_200
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key issued by Staple.
    bearerAuth:
      type: http
      scheme: bearer
      description: JWT obtained from the login endpoint.

```

## Examples

### Scan Asynchronous Multiple Documents



**Request**

```json
{}
```

**Response**

```json
{
  "asyncScanMultipleDocuments": {
    "documents": [
      {
        "docId": 1,
        "docName": "invoice.pdf"
      },
      {
        "docId": 2,
        "docName": "invoice2.pdf"
      }
    ],
    "message": "The documents are being processed. Please wait a few minutes or so. Processing will depend on the number of documents and their size."
  }
}
```

**SDK Code**

```python Scan Asynchronous Multiple Documents
import requests

url = "https://api.staple.io/v2/documents/scan/async-documents"

payload = "-----011000010111000001101001--\r\n"
headers = {
    "x-api-key": "<apiKey>",
    "Content-Type": "multipart/form-data; boundary=---011000010111000001101001"
}

response = requests.post(url, data=payload, headers=headers)

print(response.json())
```

```javascript Scan Asynchronous Multiple Documents
const url = 'https://api.staple.io/v2/documents/scan/async-documents';
const form = new FormData();

const options = {method: 'POST', headers: {'x-api-key': '<apiKey>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Scan Asynchronous Multiple Documents
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.staple.io/v2/documents/scan/async-documents"

	payload := strings.NewReader("-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Scan Asynchronous Multiple Documents
require 'uri'
require 'net/http'

url = URI("https://api.staple.io/v2/documents/scan/async-documents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request.body = "-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java Scan Asynchronous Multiple Documents
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.staple.io/v2/documents/scan/async-documents")
  .header("x-api-key", "<apiKey>")
  .body("-----011000010111000001101001--\r\n")
  .asString();
```

```php Scan Asynchronous Multiple Documents
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.staple.io/v2/documents/scan/async-documents', [
  'headers' => [
    'Content-Type' => 'multipart/form-data; boundary=---011000010111000001101001',
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Scan Asynchronous Multiple Documents
using RestSharp;

var client = new RestClient("https://api.staple.io/v2/documents/scan/async-documents");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddHeader("Content-Type", "multipart/form-data; boundary=---011000010111000001101001");
request.AddParameter("undefined", "-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Scan Asynchronous Multiple Documents
import Foundation

let headers = ["x-api-key": "<apiKey>"]
let parameters = []

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://api.staple.io/v2/documents/scan/async-documents")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Documents_scanAsynchronousMultipleDocuments_example



**Request**

```json
{
  "files": "<file: string>",
  "handwritten": "[true]",
  "qid": "1"
}
```

**Response**

```json
{
  "asyncScanMultipleDocuments": {
    "documents": [
      {
        "docId": 1,
        "docName": "invoice.pdf"
      },
      {
        "docId": 2,
        "docName": "invoice2.pdf"
      }
    ],
    "message": "The documents are being processed. Please wait a few minutes or so. Processing will depend on the number of documents and their size."
  }
}
```

**SDK Code**

```python Documents_scanAsynchronousMultipleDocuments_example
import requests

url = "https://api.staple.io/v2/documents/scan/async-documents"

files = { "files": "open('string', 'rb')" }
payload = {
    "handwritten": "[true]",
    "qid": "1"
}
headers = {"x-api-key": "<apiKey>"}

response = requests.post(url, data=payload, files=files, headers=headers)

print(response.json())
```

```javascript Documents_scanAsynchronousMultipleDocuments_example
const url = 'https://api.staple.io/v2/documents/scan/async-documents';
const form = new FormData();
form.append('files', 'string');
form.append('handwritten', '[true]');
form.append('qid', '1');

const options = {method: 'POST', headers: {'x-api-key': '<apiKey>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Documents_scanAsynchronousMultipleDocuments_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.staple.io/v2/documents/scan/async-documents"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"handwritten\"\r\n\r\n[true]\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"qid\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Documents_scanAsynchronousMultipleDocuments_example
require 'uri'
require 'net/http'

url = URI("https://api.staple.io/v2/documents/scan/async-documents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"handwritten\"\r\n\r\n[true]\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"qid\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java Documents_scanAsynchronousMultipleDocuments_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.staple.io/v2/documents/scan/async-documents")
  .header("x-api-key", "<apiKey>")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"handwritten\"\r\n\r\n[true]\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"qid\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php Documents_scanAsynchronousMultipleDocuments_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.staple.io/v2/documents/scan/async-documents', [
  'multipart' => [
    [
        'name' => 'files',
        'filename' => 'string',
        'contents' => null
    ],
    [
        'name' => 'handwritten',
        'contents' => '[true]'
    ],
    [
        'name' => 'qid',
        'contents' => '1'
    ]
  ]
  'headers' => [
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Documents_scanAsynchronousMultipleDocuments_example
using RestSharp;

var client = new RestClient("https://api.staple.io/v2/documents/scan/async-documents");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"string\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"handwritten\"\r\n\r\n[true]\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"qid\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Documents_scanAsynchronousMultipleDocuments_example
import Foundation

let headers = ["x-api-key": "<apiKey>"]
let parameters = [
  [
    "name": "files",
    "fileName": "string"
  ],
  [
    "name": "handwritten",
    "value": "[true]"
  ],
  [
    "name": "qid",
    "value": "1"
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://api.staple.io/v2/documents/scan/async-documents")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```