> For the complete documentation index, see [llms.txt](https://docs.auditbase.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.auditbase.com/api-access/v-1.0/scan-api/create-file-upload-scans.md).

# Create File Upload Scans

## Create a New Scan

<mark style="color:green;">`POST`</mark> `/v1/scans/upload`

The `/v1/scans/upload` endpoint allows you to create a scan which analyzes the Solidity files sent in the request.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <api_key>` |

**Body**

The body is a "parms" JSON object with the following keys

| Name         | Type   | Description                                                         |
| ------------ | ------ | ------------------------------------------------------------------- |
| name         | string | Scan label                                                          |
| `files`      | JSON   | {"file1.sol": "file content",  ... ,"filelast.sol": "file content"} |
| webhook\_url | string | URL where you would like the results sent in a post request         |

**Example**

```python
file1 = Path('./example.sol').read_text()
file2 = Path('./example2.sol').read_text()
file3 = Path('./example3.sol').read_text()
    
key = "<your auditbase key>"
route = 'v1/scans/upload'
url = host + route
post_data = {
    "params":{
        "name": "scan1",
        "files": {"file1.sol": file1, "file2.sol": file2, "file3.sol": file3},
        "webhook_url": "https://<your call url>/webhook",
    },
}

headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {key}',
}

response = requests.post(url, json=post_data, headers=headers)
print("response: ", response.json())

```

**Response**

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

<pre class="language-json"><code class="lang-json">{
  "success": true,
<strong>  "scan_id": "60188023-0b6f-4994-ba15-3d973efb0711",
</strong>  "webhook_url": "your-specified-callback-url.com"
}
</code></pre>

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "Invalid request"
}
```

{% endtab %}
{% endtabs %}

**Webhook Response**

Once a scan completes, AuditBase will callback a webhook with the following data:&#x20;

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

````json
{
   "success":true,
   "scan_id":"60188023-0b6f-4994-ba15-3d973efb0711",
   "data":{
      "findings":[
         {
            "id":"cb775b85-a334-4096-bbb6-1ec3540b46c4",
            "title":"Centralization risk for trusted owners",
            "description":"Having a single EOA as the only owner of contracts is a large centralization risk and a single point of failure. A single private key may be taken in a hack, or the sole holder of the key may become unable to retrieve the key when necessary. Consider changing to a multi-signature setup, or having a role-based authorization model.",
            "identifier":"M001",
            "count":1,
            "gas_savings":"-",
            "severity":"M",
            "snippet":"```solidity\nFile: tmp/0bd226dd-a4da-4dbe-8005-6616cae58949/contract.sol\n\n559         function renounceOwnership() public onlyOwner {\n568         function transferOwnership(address newOwner) public onlyOwner {\n602         function changeName(string memory name) public onlyOwner{\n\n```\n"
         },
         {
            "id":"bae2e591-5fca-48ed-8233-eaceec8649c2",
            "title":"Use `Ownable2Step` rather than `Ownable`",
            "description":"`Ownable2Step` and `Ownable2StepUpgradeable` prevent the contract ownership from mistakenly being transferred to an address that cannot handle it (e.g. due to a typo in the address), by requiring that the recipient of the owner permissions actively accept via a contract call of its own.",
            "identifier":"L001",
            "count":1,
            "gas_savings":"-",
            "severity":"L",
            "snippet":"```solidity\nFile: tmp/0bd226dd-a4da-4dbe-8005-6616cae58949/contract.sol\n\n590     contract Token is ERC20, ERC20Detailed, ERC20Burnable, Ownable {\n\n```\n"
         },
         {
            "id":"d49b8e59-5c39-4a28-9500-bd1a434e8125",
            "title":"Burn functions should be protected with a modifier",
            "description":"  ",
            "identifier":"L002",
            "count":1,
            "gas_savings":"-",
            "severity":"L",
            "snippet":"```solidity\nFile: tmp/0bd226dd-a4da-4dbe-8005-6616cae58949/contract.sol\n\n492         function burn(uint256 amount) public {\n493             _burn(msg.sender, amount);\n494         }\n\n```\n"
         },
         {
            "id":"e489b2cf-7385-4945-a971-d2a2d56a5831",
            "title":"No limits when setting state variable amounts",
            "description":"It is important to ensure state variables numbers are set to a reasonable value.",
            "identifier":"L003",
            "count":1,
            "gas_savings":"-",
            "severity":"L",
            "snippet":"```solidity\nFile: tmp/0bd226dd-a4da-4dbe-8005-6616cae58949/contract.sol\n\n441             _decimals = decimals;\n\n```\n"
         }
      ]
   }
}
````

{% endtab %}
{% endtabs %}
