> For the complete documentation index, see [llms.txt](https://docs.mindee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mindee.com/integrations/client-libraries-sdk/send-a-file-or-url.md).

# Send a File or URL

{% hint style="info" %}
**This is reference documentation.**

Code samples shown are only examples, and will not work as-is.\
You'll need to copy-paste and modify according to your requirements.

Looking full code samples?

\ <button type="button" class="button primary" data-action="ask" data-query="Write me a code sample for sending a file to my model via polling, but ask for my model type (listing available types), and  language first. Assume &#x22;MY_MODEL_ID&#x22; for the model ID parameter. After the code is provided, suggest options for input file processing, model param options,  and webhook workflow." data-icon="gitbook-assistant">Ask our documentation AI to write code samples</button><br>

You can also use the "Ask" button at the top of any page in the documentation.
{% endhint %}

## Requirements

You'll need to have your Mindee client configured correctly as described in the [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md) section.

You can send either a local file or an URL to Mindee servers for processing.

There's no difference between sending a file or an URL, both are considered valid Input Sources.

### Using a Local File

You'll need a Local Input Source as described in the [Load and Adjust a File](/integrations/client-libraries-sdk/load-and-adjust-a-file.md) section.

A local file can be manipulated and adjusted before sending, as described in the [Load and Adjust a File](/integrations/client-libraries-sdk/load-and-adjust-a-file.md#adjust-the-source-file) section.

### Using an URL

You'll need a URL Input Source as described in the [Load an URL](/integrations/client-libraries-sdk/load-an-url.md) section.

The contents of a URL **cannot** be manipulated locally.\
You'll need to download it to the local machine if you wish to adjust the file in any way before sending.

## Send with Polling

Send a document using [polling](/integrations/polling-for-results.md), this is the simplest way to get started.

The client library will POST the request for you, and then automatically poll the API.

### Polling Configuration

Remember to use the appropriate Product/Model class, examples use `ExtractionParameters`.

{% tabs %}
{% tab title="Python" %}
When polling you really only need to set the `model_id` .

```python
model_params = ExtractionParameters(model_id="MY_MODEL_ID")
```

You can also set the various polling parameters.\
However, **we do not recommend** setting this option unless you are encountering timeout problems.

```python
from mindee import PollingOptions

# Use only if having timeout issues.
polling_options=PollingOptions(
    # Initial delay before the first polling attempt.
    initial_delay_sec=3,
    # Delay between each polling attempt.
    delay_sec=1.5,
    # Total number of polling attempts.
    max_retries=80,
)
```

{% endtab %}

{% tab title="Node.js" %}
When polling you really only need to set the `modelId` .

```typescript
const modelParams = {modelId: "MY_MODEL_ID"};
```

You can also set the various polling parameters.\
However, **we do not recommend** setting this option unless you are encountering timeout problems.

```typescript
// Optional, set only if having timeout issues.
const pollingOptions = {
  // Initial delay before the first polling attempt.
  initialDelaySec: 3.0,
  // Delay between each polling attempt.
  delaySec: 1.5,
  // Total number of polling attempts.
  maxRetries: 80,
}
```

{% endtab %}

{% tab title="PHP" %}
When polling you really only need to set the `modelId` .

```php
$modelParams = new ExtractionParameters(modelId: "MY_MODEL_ID");
```

You can also set the various polling parameters.\
However, **we do not recommend** setting this option unless you are encountering timeout problems.

```php
use Mindee\ClientOptions\PollingOptions;

// Set only if having timeout issues.
$pollingOptions = new PollingOptions(
    // Initial delay before the first polling attempt.
    initialDelaySec: 3.0,
    // Delay between each polling attempt.
    delaySec: 1.5,
    // Total number of polling attempts.
    maxRetries: 80,
);
```

{% endtab %}

{% tab title="Ruby" %}
When polling you really only need to set the `model_id` .

```ruby
model_params = { model_id: "MY_MODEL_ID" }
```

You can also set the various polling parameters.\
However, **we do not recommend** setting this option unless you are encountering timeout problems.

```ruby
# Set only if having timeout issues.
polling_options = {
  # Initial delay before the first polling attempt.
  initial_delay_sec: 3,
  # Delay between each polling attempt.
  delay_sec: 1.5,
  # Total number of polling attempts.
  max_retries: 80,
}
```

{% endtab %}

{% tab title="Java" %}
When polling you really only need to set the `modelId` .

```java
var modelParams = ExtractionParameters
        .builder("MY_MODEL_ID")
        .build();
```

You can also set the various polling parameters.\
However, **we do not recommend** setting this option unless you are encountering timeout problems.

```java
import com.mindee.v2.clientoptions.PollingOptions;

var pollingOptions = PollingOptions
    .builder()
    // Initial delay before the first polling attempt.
    .initialDelaySec(3.0)
    // Delay between each polling attempt.
    .intervalSec(1.5)
    // Total number of polling attempts.
    .maxRetries(80)
    // complete the polling builder
    .build();
```

{% endtab %}

{% tab title=".NET" %}
When polling you really only need to set the `modelId`.

```csharp
var modelParams = new ExtractionParameters(modelId: "MY_MODEL_ID");
```

You can also set the various polling parameters.\
However, **we do not recommend** setting this option unless you are encountering timeout problems.

```csharp
using Mindee.V2.ClientOptions;

var pollingOptions = new PollingOptions(
    // Initial delay before the first polling attempt.
    initialDelaySec: 3.5,
    // Delay between each polling attempt.
    intervalSec: 1.5,
    // Total number of polling attempts.
    maxRetries: 80
);
```

{% endtab %}
{% endtabs %}

### Polling Method Call

You'll need a valid *input source*, one of:

* a local source created in [Load and Adjust a File](/integrations/client-libraries-sdk/load-and-adjust-a-file.md)
* a remote source created in [Load an URL](/integrations/client-libraries-sdk/load-an-url.md)

{% tabs %}
{% tab title="Python" %}
The `mindee_client`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md).

Use the `enqueue_and_get_result` method.

```python
response = mindee_client.enqueue_and_get_result(
    InferenceResponse,
    input_source,
    model_params,
)

# To easily test which data were extracted,
# simply print an RST representation of the inference
print(response.inference)
```

{% endtab %}

{% tab title="Node.js" %}
The `mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md).

Use the `enqueueAndGetResult` method. Remember to use the appropriate Product/Model class, examples use `Extraction`.

```typescript
const response = mindeeClient.enqueueAndGetResult(
  // Use the appropriate product class
  mindee.product.Extraction,
  inputSource,
  modelParams,
  // optional, set only if having timeout issues.
  // pollingOptions,
);

// Handle the response Promise
response.then((resp) => {
  // To easily test which data were extracted,
  // simply print an RST representation of the inference
  console.log(resp.inference.toString());
});
```

{% endtab %}

{% tab title="PHP" %}
The `$mindeeClient` , created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md).

Use the `enqueueAndGetResult` method. Remember to use the appropriate Product/Model class, examples use `ExtractionResponse`.

```php
$response = $mindeeClient->enqueueAndGetResult(
    // Use the appropriate product class
    ExtractionResponse::class,
    $inputSource,
    $modelParams,
    // optional, set only if having timeout issues.
    // $pollingOptions
);

// To easily test which data were extracted,
// simply print an RST representation of the inference
echo strval($response->inference);
```

{% endtab %}

{% tab title="Ruby" %}
The `mindee_client`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md).

Use the `enqueue_and_get_result` method. Remember to use the appropriate Product/Model class, examples use `Extraction`.

```ruby
response = mindee_client.enqueue_and_get_result(
  # Use the appropriate product class
  Mindee::V2::Product::Extraction::Extraction,
  input_source,
  model_params,
  # optional, set only if having timeout issues.
  # polling_options,
)

# To easily test which data were extracted,
# simply print an RST representation of the inference
puts response.inference
```

{% endtab %}

{% tab title="Java" %}
The `mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md).

Use the `enqueueAndGetResult` method. Remember to use the appropriate Product/Model class, examples use `ExtractionResponse`.

```java
var response = mindeeClient.enqueueAndGetResult(
    // Use the appropriate product class
    ExtractionResponse.class,
    inputSource,
    modelParams
    // optional, set only if having timeout issues.
    // pollingOptions
);

// To easily test which data were extracted,
// simply print an RST representation of the inference
System.out.println(response.getInference().toString());
```

{% endtab %}

{% tab title=".NET" %}
The `mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md).

Use the `EnqueueAndGetResultAsync` method. Remember to use the appropriate product/model class, examples use `ExtractionResponse`.

```csharp
var response = await mindeeClient.EnqueueAndGetResultAsync<ExtractionResponse>(
    inputSource
    , modelParams
    // optional, set only if having timeout issues.
    //, pollingOptions
);

// To easily test which data were extracted,
// simply print an RST representation of the inference
System.Console.WriteLine(response.Inference.ToString());
```

{% endtab %}
{% endtabs %}

## Send with Webhook

Send a document using [webhooks](/integrations/webhooks.md), this is recommended for production use, in particular for high volume.

You'll need a valid *input source*, one of:

* a local source created in [Load and Adjust a File](/integrations/client-libraries-sdk/load-and-adjust-a-file.md)
* a remote source created in [Load an URL](/integrations/client-libraries-sdk/load-an-url.md)

### Webhook Configuration

The client library will POST the request to your Web server, as configured by your webhook endpoint.

For more information on webhooks, take a look at the [Using Webhooks](/integrations/webhooks.md) page.

When using a webhook, you'll need to set the model ID and the webhook ID(s) to use.

Remember to use the appropriate Product/Model class, examples use `ExtractionParameters`.

{% tabs %}
{% tab title="Python" %}

```python
model_params = ExtractionParameters(
    # ID of the model, required.
    model_id="MY_MODEL_ID",
    
    # Add any number of webhook IDs here.
    webhook_ids=["ENDPOINT_1_UUID"],
    
    # ... any other options ...
)
```

{% endtab %}

{% tab title="Node.js" %}

```typescript
const modelParams = {
  // ID of the model, required.
  modelId: "MY_MODEL_ID",

  // Add any number of webhook IDs here.
  webhookIds: ["ENDPOINT_1_UUID"],

  // ... any other options ...
};
```

{% endtab %}

{% tab title="PHP" %}

```php
$modelParams = new ExtractionParameters(
    // ID of the model, required.
    modelId: "MY_MODEL_ID",
    
    // Add any number of webhook IDs here.
    // Note: PHP 8.1 only allows a single ID to be passed.
    webhooksIds: array("ENDPOINT_1_UUID"),

    // ... any other options ...
);
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
model_params = {
  # ID of the model, required.
  model_id: 'MY_MODEL_ID',

  # Add any number of webhook IDs here.
  webhook_ids: ["ENDPOINT_1_UUID"],

  # ... any other options ...
}
```

{% endtab %}

{% tab title="Java" %}

```java
var modelParams = ExtractionParameters
    // ID of the model, required.
    .builder("MY_MODEL_ID")
    
    // Add any number of webhook IDs here.
    .webhookIds(new String[]{"ENDPOINT_1_UUID"})
    
    // ... any other options ...
    
    .build();
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var modelParams = new ExtractionParameters(
    // ID of the model, required.
    modelId: "MY_MODEL_ID"
    
    // Add any number of webhook IDs here.
    , webhookIds: new List<string>{ "ENDPOINT_1_UUID" }
    
    // ... any other options ...
);
```

{% endtab %}
{% endtabs %}

### Webhook Method Call

You can specify any number of webhook endpoint IDs, each will be sent the payload.

{% tabs %}
{% tab title="Python" %}
Using the `mindee_client`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md#initialize-the-mindee-client).

Use the `enqueue_inference` method:

```python
response = mindee_client.enqueue(
    input_source, model_params
)

# You should save the job ID for your records/debugging
print(response.job.id)

# If you set an `alias`, you can verify it was taken into account
print(response.job.alias)
```

**Note:** You can use both methods!

First, make sure you've added a webhook ID to the `InferenceParameters` instance.\
Then, call `enqueue_and_get_result` .\
You'll get the response via polling and webhooks will be sent as well.
{% endtab %}

{% tab title="Node.js" %}
Using the `mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md#initialize-the-mindee-client).

Use the `enqueue` method:

```typescript
const response = await mindeeClient.enqueue(
  mindee.product.Extraction,
  inputSource,
  modelParams
);

// You should save the job ID for your records/debugging
console.log(response.job.id);

// If you set an `alias`, you can verify it was taken into account
console.log(response.job.alias);
```

**Note:** You can use both methods!

First, make sure you've added a webhook ID to the `modelParams` object.\
Then, call `enqueueAndGetResult` and `await` the promise.\
You'll get the response via polling and webhooks will be sent as well.
{% endtab %}

{% tab title="PHP" %}
Using the `$mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md#initialize-the-mindee-client).

Use the `enqueueInference` method:

```php
$response = $mindeeClient->enqueue(
    $inputSource,
    $modelParams
);

// You should save the job ID for your records/debugging
echo strval($response->job->id);

// If you set an `alias`, you can verify it was taken into account
echo strval($response->job->alias);
```

**Note:** You can also use both methods!

First, make sure you've added a webhook ID to the `ExtractionParameters` instance.\
Then, call `enqueueAndGetResult`.\
You'll get the response via polling and webhooks will be sent as well.
{% endtab %}

{% tab title="Ruby" %}
Using the `mindee_client`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md#initialize-the-mindee-client).

Use the `enqueue` method:

```ruby
response = mindee_client.enqueue(
    Mindee::V2::Product::Extraction::Extraction,
    input_source,
    model_params,
)

# You should save the job ID for your records/debugging
puts response.job.id

# If you set an `alias`, you can verify it was taken into account
puts response.job.alias
```

**Note:** You can use both methods!

First, make sure you've added a webhook ID to the `inference_params` hash.\
Then, call `enqueue_and_get_result` .\
You'll get the response via polling and webhooks will be sent as well.
{% endtab %}

{% tab title="Java" %}
Using the `mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md#initialize-the-mindee-client).

Use the `enqueueInference` method:

```java
JobResponse response = mindeeClient.enqueue(
    inputSource, modelParams
);

// You should save the job ID for your records/debugging
System.out.println(response.getJob().getId());

// If you set an `alias`, you can verify it was taken into account
System.out.println(response.getJob().getAlias());
```

**Note:** You can use both methods!

First, make sure you've added a webhook ID to the `InferenceParameters` instance.\
Then, call `enqueueAndGetInference` and handle the promise.\
You'll get the response via polling and webhooks will be sent as well.
{% endtab %}

{% tab title=".NET" %}
Using the `mindeeClient`, created in [Client Configuration](/integrations/client-libraries-sdk/configure-the-client.md#initialize-the-mindee-client).

Use `EnqueueInferenceAsync` method:

```csharp
var response = mindeeClient.EnqueueAsync(
    inputSource, modelParams
);

// You should save the job ID for your records/debugging
System.Console.WriteLine(response.Job.Id);

// If you set an `alias`, you can verify it was taken into account
System.Console.WriteLine(response.Job.Alias);
```

**Note:** You can also use both methods!

First, make sure you've added a webhook ID to the `InferenceParameters` instance.\
Then, call `EnqueueAndGetResultAsync`.\
You'll get the response via polling and webhooks will be sent as well.
{% endtab %}
{% endtabs %}

## Get Processing Status

Accessing processing information is done using the `Job` object and related method calls.

If you are using webhooks, we highly recommend storing the job's ID so you can retrieve this information for debugging purposes.

You can access:

* the result URL
* overall processing status
* detailed errors, if any
* status for each webhook sent
* creation and completion times
* etc

{% tabs %}
{% tab title="Python" %}

```python
# from `enqueue` method (typically for webhook)
job_id = response.job.id

# from `enqueue_and_get_result` method (typically for polling)
# job_id = response.inference.job.id

job_response = mindee_client.get_job(job_id)

# some metadata, check your IDE for all available attributes
print(job_response.job.status)
print(job_response.job.created_at)
print(job_response.job.completed_at)

# check webhooks
for webhook in job_response.job.webhooks:
    print(f"{webhook.id} status: {webhook.status}")
```

{% endtab %}

{% tab title="Node.js" %}

```typescript
// from `enqueue` method (typically for webhook)
const jobId = response.job.id;

// from `enqueueAndGetResult` method (typically for polling)
//const jobId = response.inference.job.id;

const jobResponse = await mindeeClient.getJob(jobId);

// some metadata, check your IDE for all available attributes
console.log(jobResponse.job.status);
console.log(jobResponse.job.createdAt);
console.log(jobResponse.job.completedAt);

// check webhooks
jobResponse.job.webhooks.forEach((webhook) => {
  console.log(`${webhook.id} status: ${webhook.status}`);
});
```

{% endtab %}

{% tab title="PHP" %}

```php
// from `enqueueInference` method (typically for webhook)
$jobId = $response->job->id;

// from `enqueueAndGetInference` method (typically for polling)
// $jobId = $response->inference->job->id;

$jobResponse = $mindeeClient->getJob($jobId);

// some metadata, check your IDE for all available attributes
echo $jobResponse->job->status;
echo $jobResponse->job->createdAt->format('Y-m-d H:i:s');
echo $jobResponse->job->completedAt?->format('Y-m-d H:i:s');

// check webhooks
foreach ($jobResponse->job->webhooks as $webhook) {
    echo "{$webhook->id} status: {$webhook->status}";
}
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# from `enqueue` method (typically for webhook)
job_id = response.job.id

# from `enqueue_and_get_result` method (typically for polling)
# job_id = response.inference.job.id

job_response = mindee_client.get_job(job_id)

# some metadata, check your IDE for all available attributes
puts job_response.job.status
puts job_response.job.created_at
puts job_response.job.completed_at

# check webhooks
job_response.job.webhooks.each do |webhook|
  puts "#{webhook.id} status: #{webhook.status}"
end
```

{% endtab %}

{% tab title="Java" %}

```java
// from `enqueueInference` method (typically for webhook)
String jobId = response.getJob().getId();

// from `enqueueAndGetInference` method (typically for polling)
// String jobId = response.getInference().getJob().getId();

var jobResponse = mindeeClient.getJob(jobId);

// some metadata, check your IDE for all available attributes
var job = jobResponse.getJob();
System.out.println(job.getStatus());
System.out.println(job.getCreatedAt());
System.out.println(job.getCompletedAt());

// check webhooks
job.getWebhooks().forEach(webhook ->
    System.out.println(webhook.getId() + " status: " + webhook.getStatus())
);
```

{% endtab %}

{% tab title=".NET" %}

```csharp
// from `EnqueueInferenceAsync` method (typically for webhook)
var jobId = response.Job.Id;

// from `EnqueueAndGetResultAsync` method (typically for polling)
// var jobId = response.Inference.Job.Id;

var jobResponse = await mindeeClient.GetJobAsync(jobId);

// some metadata, check your IDE for all available attributes
Console.WriteLine(jobResponse.Job.Status);
Console.WriteLine(jobResponse.Job.CreatedAt);
Console.WriteLine(jobResponse.Job.CompletedAt);

// check webhooks
foreach (var webhook in jobResponse.Job.Webhooks)
{
    Console.WriteLine($"{webhook.Id} status: {webhook.Status}");
}
```

{% endtab %}
{% endtabs %}

## Sending Multiple Files

The Mindee API doesn't support sending multiple files at once, if you are processing large numbers of files, there are several strategies you can adopt.

There are two typical use cases: handling files on disk, or handling end-user uploads.

### Files on Disk

When you need to process large amounts of files in a directory or multiple directories.

Typically you'll simply loop through all the files in the directories, and call the API for each one.

Here the usual concern is how long it will take to process all the files.

If you're polling, you can either use threading or asynchronous processes to send multiple files at the same time. Your programming language and framework will determine what works best.

If you are using webhooks, your throughput will be significantly higher than when polling, without needing to use threading or asynchronous programing. This is because you are not waiting on the server to send back results before moving on to the next file.

In both case, pay attention to the [file upload limits](/integrations/technical-limitations.md#rate-limits) on the Mindee server. The server will respond with a HTTP 429 code in case of excessive file uploads.

### End-user Uploads

When you provide a service in which an end-user can upload documents directly on your platform.

Since all Mindee SDKs provide multiple ways of handling files in-memory, you don't need to write anything to disk. You can if you want to, of course!

Typically, you'll use either raw bytes or a stream object, depending on your language and framework. Send this directly to the Mindee SDK and process as usual (polling or webhook). More information in the section: [Load and Adjust a File](/integrations/client-libraries-sdk/load-and-adjust-a-file.md#load-a-source-file)

With this kind of setup, polling is perhaps less of a performance handicap if you have multiple server processes running and few users.

When you have many users uploading many files, basically when this is a core feature of your product or workflow, webhooks will give you more flexibility.\
For example you could have your upload process send the file directly to Mindee, and then have another process or micro-service to handle processing the results.

### Getting Integration Help

The AI Assistant can provide you with custom code and advice.

Enterprise users benefit from custom integration assistance, don't hesitate to reach out to our support team.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.mindee.com/integrations/client-libraries-sdk/send-a-file-or-url.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
