# Uploading files and URLs

{% hint style="info" %}
Felt supports a myriad of formats, both as files and hosted URLs, up to a limit of 5GB. Check out the full list [in our Help Center](https://app.gitbook.com/o/pBjb4u9vDMMo5uYBgN6o/s/mRfGitkyjOEMvVsEyGWN/).
{% endhint %}

## Uploading a URL

The easiest way of uploading data into a Felt map via the API is to import from a URL. Here's an example importing all the recent earthquakes from [the USGS' live GeoJSON feed](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php):

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

```bash
# Your API token and map ID should look like this:
# FELT_API_TOKEN="felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
# MAP_ID="CjU1CMJPTAGofjOK3ICf1D"
FELT_API_TOKEN="<YOUR_API_TOKEN>"
MAP_ID="<YOUR_MAP_ID>"

curl -L \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${FELT_API_TOKEN}" \
  "https://felt.com/api/v2/maps/${MAP_ID}/upload" \
  -d '{"import_url":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson", "name": "USGS Earthquakes"}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

# Your API token should look like this:
# api_token = "felt_pat_ABCDEFUDQPAGGNBmX40YNhkCRvvLI3f8/BCwD/g8"
api_token = "<YOUR_API_TOKEN>"
map_id = "<YOUR_MAP_ID>"

r = requests.post(
  f"http://felt.com/api/v2/maps/{map_id}/upload",
  json={
    "import_url":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson",
    "name": "USGS Earthquakes",
  },
  headers={"Authorization": f"Bearer {api_token}"}
)
assert r.ok
layer_id = r.json()["layer_id"]
```

{% endtab %}

{% tab title="felt-python" %}

```python
import os

from felt_python import upload_url

# Setting your API token as an env variable can save
# you from repeating it in every function call
os.environ["FELT_API_TOKEN"] = "<YOUR_API_TOKEN>"

map_id = "<YOUR_MAP_ID>"

url_upload = upload_url(
    map_id=map_id,
    layer_url="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson",
    layer_name="USGS Earthquakes",
)
layer_id = url_upload["layer_id"]
```

{% endtab %}
{% endtabs %}

Like maps, layers also have unique identifiers. Make sure to take note of them for subsequent calls, like styling a layer or removing it.

## Uploading a file

{% hint style="info" %}
Uploading a file is a single function call using the `felt-python` library.
{% endhint %}

Files aren't uploaded to the Felt app — instead, they're uploaded directly to Amazon S3. Therefore, creating a layer from a file on your computer is a two-step process:

### 1. Request an upload via the Felt API

Perform a `POST` request to receive an S3 presigned URL which you can later upload your files to:

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

```python
r = requests.post(
    f"https://felt.com/api/v2/maps/{map_id}/upload",
    headers={
        "Authorization": f"Bearer {api_token}",
        "Content-Type": "application/json",
    },
    json={"name": "My new layer"},
)
assert r.ok
layer_id = r.json()["layer_id"]

presigned_upload = r.json()
```

{% endtab %}

{% tab title="felt-python" %}

```python
from felt_python import upload_file

file_name = "<YOUR_FILE_WITH_EXTENSION>" # Example: regions.geojson

upload_file(
  map_id=map_id,
  file_name="YOUR_FILE_WITH_EXTENSION",
  layer_name="My new layer",
)
```

{% endtab %}
{% endtabs %}

### 2. Upload your file(s) to Amazon s3

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

```python
# This code is a continuation of the previous Python code block
# and assumes you already have a "presigned_upload" variable

file_name = "<YOUR_FILE_WITH_EXTENSION>" # Example: regions.geojson

url = presigned_upload["url"]
presigned_attributes = presigned_upload["presigned_attributes"]
# A 204 response indicates that the upload was successful
with open(file_name, "rb") as file_obj:
    output = requests.post(
        url,
        # Order is important, file should come at the end
        files={**presigned_attributes, "file": file_obj},
    )
```

{% endtab %}

{% tab title="felt-python" %}

```python
# Nothing! Uploading a file is a single step with the felt-python library
```

{% endtab %}
{% endtabs %}

## Monitoring progress

You can check the upload status of a layer by querying it:

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

```bash
curl -L \
  "https://felt.com/api/v2/maps/${MAP_ID}/layers/{LAYER_ID}" \
  -H "Authorization: Bearer ${YOUR_API_TOKEN}"
```

{% endtab %}

{% tab title="Python" %}

```python
r = requests.get(
    f"https://felt.com/api/v2/maps/{map_id}/layers/{layer_id}",
    headers={"Authorization": f"Bearer {api_token}"},
)
assert r.ok
print(r.json()["progress"])
```

{% endtab %}

{% tab title="felt-python" %}

```python
from felt_python import get_layer_details

get_layer_details(map_id, layer_id)["progress"]
```

{% endtab %}
{% endtabs %}
