# Data Transfer

We support two main ways of transferring product data between your shop and our infrastructure.

## Pull

We periodically download your product data files from a given origin using any of the following protocols:

* HTTP(S)
  * requires a `"Content-Type"` header indicating the feed format, e.g. `text/csv`
  * supports optional `gzip` compression, if specified in a `"Content-Encoding"` header
* (S)FTP
  * requires a file extension indicating the feed format, e.g. `.csv`
* AWS S3
  * requries a `"Content-Type"` metadata indicating the feed format, e.g. `text/csv`

Each of these protocols can be used with and without credentials — if you have non-standard requirements, just talk to us and we'll find a way :yellow\_heart:

## Push

You upload your product data files whenever something updates to our S3 bucket.\
You request a signed upload URL from our API and can then upload your file. You just need to make 2 simple HTTP calls for that.

{% hint style="success" %}
Your files are encrypted on our side and can not be accessed from the outside.
{% endhint %}

![](/files/KHb4l8fLmbouYhwWzmwZ)

### How it works

1. Send a HTTP POST request to `api.8select.io/feeds/uploads` to retrieve a pre-signed upload request, i.e. a JSON object containing the following properties:
   * `headers`: A map of string key-value pairs
   * `method`: A HTTP method, e.g. `PUT`
   * `url`: A presigned URL
2. Send a second HTTP request using the `method` and `url`, **and including all** `headers` returned by the previous request, as well as the file to be uploaded in the HTTP body.

### API

#### get a pre-signed request for product feed upload

<mark style="color:green;">`POST`</mark> `https://api.8select.io/feeds/uploads`

#### Headers

<table><thead><tr><th width="208.296875">Name</th><th width="180.7313232421875">Type</th><th>Description</th></tr></thead><tbody><tr><td>x-api-id<mark style="color:red;">*</mark></td><td>String</td><td>Your API ID provided by us.</td></tr><tr><td>x-api-secret<mark style="color:red;">*</mark></td><td>String</td><td>Your API SECRET provided by us.</td></tr><tr><td>content-type<mark style="color:red;">*</mark></td><td>application/json</td><td></td></tr></tbody></table>

#### Request Body

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

<table><thead><tr><th width="177.1312255859375">Name</th><th width="131">Type</th><th>Description</th></tr></thead><tbody><tr><td>identifier<mark style="color:red;">*</mark></td><td>String</td><td>The field by which a record can be uniquely identified, e.g. <code>sku</code> or <code>product_id</code> </td></tr><tr><td>format<mark style="color:red;">*</mark></td><td>Object</td><td><pre class="language-json" data-overflow="wrap"><code class="lang-json">{ 
  "options": { 
    "delimiter": "," 
  }, 
  "type": "csv" 
}
</code></pre></td></tr><tr><td>delta</td><td>Boolean</td><td><p>If set to <code>false</code> we will mark all products that are not present in the feed as deleted.</p><p>If set to <code>true</code> we will just update the products contained in the feed and keep all other products as is.</p><p></p><p>That way you can push so called delta-feeds that only include changes and save ressources and you and our side.</p><p></p><p><code>true</code> or <code>false</code><br><br>defaults to <code>false</code></p></td></tr></tbody></table>
{% endtab %}

{% tab title="example" %}

```json
{
  "delta": true,
  "format": {
    "options": {
      "delimiter": ","
    },
    "type": "csv"
  },
  "identifier": "product_id"
}
```

{% endtab %}
{% endtabs %}

#### Response

{% tabs %}
{% tab title="200: OK " %}

```typescript
{
    "headers": {
        "Content-Type": "text/csv; charset=utf-8", // depending on the request parameters
        "X-Amz-Meta-Delimiter": ",", // depending on the request parameters
        "X-Amz-Meta-Sku-Field-Name": "sku", // depending on the request parameters
        ... // could be more
    },
    "method": "PUT",
    "url": "https://s3.eu-central-1.amazonaws.com/..."
}
```

{% endtab %}
{% endtabs %}

#### API usage example via cURL

This is just for demonstration purposes. You can use this method to make a test upload. For production use you should do this programatically with code on your server. :sunglasses:

Replace `your-api-secret` and `your-api-secret` with your credentials.

{% tabs %}
{% tab title="get presigned URL" %}
{% code overflow="wrap" lineNumbers="true" %}

```bash
curl -v -X POST "https://api.8select.io/feeds/uploads" -d '{ "identifier": "sku", "format": { "type": "csv","options": { "delimiter": ","}}}' -H "x-api-id:your-api-id" -H "x-api-secret:your-api-secret" -H "content-type:application/json"
```

{% endcode %}
{% endtab %}

{% tab title="upload file" %}
{% code overflow="wrap" lineNumbers="true" %}

```bash
curl -X PUT -T /path/to/your/file -H "Content-Type: text/csv" -H "X-Amz-Meta-Delimiter:," -H "X-Amz-Meta-Delta:false" -H "X-Amz-Meta-Identifier:sku" \
        "https://s3.eu-central-1.amazonaws.com/......"
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions: 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:

```
GET https://docs.8select.io/product-export/data-transfer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
