This page will help you get started with Intake API.

What is the File Intake API?

The File Intake API helps you upload files to Stairwell for analysis. Stairwell processes the files and can run them in its built-in sandbox (a safe testing environment). This process is useful if you want to analyze files for threats automatically.

How Does It Work?

Uploading files to Stairwell happens in two steps:
Preflight Check: Checks if Stairwell already has the file. If yes, you’re done!
Upload: If Stairwell hasn’t seen the file before, it provides a special link (upload URL) for you to send the file.

Before you start, make sure you have:

Asset ID: A unique identifier for the place where the file will be uploaded (you can use DefaultAsset or create a new one via Stairwell’s UI).
File Path: Where the file is located on your computer.
SHA256: A unique digital fingerprint of the file (optional but recommended).

Step 1: Preflight Check

The preflight check determines if the file is new or already in the system. To perform the check:
Copy and customize the code below:

curl --request POST \
  --url https://http.intake.app.stairwell.com/v2021.05/upload \
  --header 'Content-Type: application/json' \
  --data '{
    "asset": { "id": "<YOUR_ASSET_ID>" },
    "files": [{
      "filePath": "<YOUR_FILE_PATH>",
      "expected_attributes": {
        "identifiers": [{ "sha256": "<YOUR_FILE_SHA256>" }]
      },
      "origin": { "unspecified": {} }
    }]
  }'

Replace:
<YOUR_ASSET_ID>: The asset ID you’re using.
<YOUR_FILE_PATH>: The file’s location (e.g., C:\Users\frank\test.db).
<YOUR_FILE_SHA256>: File’s SHA256, if available.

Additional params

filesys_create_time: Timestamp of when the file was created on your system.
Format: "YYYY-MM-DDTHH:MM:SSZ"
Example: "2024-11-20T12:00:00Z"
filesys_last_modified: Timestamp of when the file was last changed on your system.
Example: "2024-11-19T10:30:00Z"
filesys_last_accessed: Timestamp of when the file was last opened or accessed.
Example: "2024-11-20T11:45:00Z"
origin: Specifies where the file came from (e.g., the web). If the file originated from the web, include additional fields like:

  • unspecified: If no origin metadata is included, or if origin: {"unspecified": {}} is added to the request, then the origin will be set to unspecified
  • web: Mark of the web! This can be used to specify from where the file was downloaded from by including the following in your request. NOTE: referrer-url, zone-id, and host-url are completely optional, you can just have origin: {"web": {}} to indicate that the file was acquired via the internet
    detonation_plan: Plan to detonate file after file is ingested. If this param is not included, it will by default be set to DETONATION_PLAN_UNSPECIFIED. If a file needs to be detonated, this can be set to DETONATE.
"origin": {
  "web": {
    "referrer-url": "testing.com",
    "host-url": "host.com",
    "zone-id": 1,
  }
}

Understand the Response:

If the response says NO_ACTION_ALREADY_EXISTS, stop here—the file is already in the system.
If the response says UPLOAD, the response should look something like this

{
  "fileActions": [
    {
      "filePath": "<filepath>",
      "expectedAttributes": {
        "identifiers": [
          {
            "sha256": "<sha256>"
          }
        ]
      },
      "uploadUrl": "<upload_url>",
      "fileField": "file",
      "method": "POST",
      "fields": {
        "key": "<key>",
        "policy": "<policy>",
        "x-goog-algorithm": "GOOG4-RSA-SHA256",
        "x-goog-credential": "[email protected]/20241120/auto/storage/goog4_request",
        "x-goog-date": "20241120T202146Z",
        "x-goog-meta-asset-id": "AAAAAA-BBBBBB-CCCCCC-DDDDDDDD",
        "x-goog-meta-file-detonate": "DETONATION_PLAN_UNSPECIFIED",
        "x-goog-meta-file-format": "RAW",
        "x-goog-meta-file-path": "/home/test/filepath",
        "x-goog-meta-sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "x-goog-signature": "67cfc4a5d1dd07adec819e309657bd6ac0c1b7db3a81822fdc3bad8342056cad3b928fa48db24bf3aeda9ff3afbc246c51274519c10d33e3720281e7ecdfcd1c85d33cf6c46b8448c14b0de473c9a73cd3a6e970ec5acf075617520a2b7c1216f1d9b0627b54bd28105e0db273a148acc3a196f16f2d7a82227b7369d850717a0d4724394d5e76d4ff26cc93c4a191ac738176447c17156e0312f67edb85eec30194da4534fea403c2cc731a6ffcaac188dc637d9273cfb33e0d573818044d481f00672edf70676dc6d3179850b3eca30a2f21073407b5d94b309e776bd0de2b149db3de4b59c1bd883b0d65195cf377c7c03fb8f1daa7259d4f0bccd155a812"
      },
      "headers": {
        "sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      },
      "action": "UPLOAD"
    }
  ]
}

This means that your environment has not yet seen the file and so the file will have to be uploaded. The form fields must be included and match the preflight response when uploading the file or else the file upload will fail.

Step 2: Upload the File

If the file needs to be uploaded, follow these steps:
Use the upload URL from the preflight response. All of the form fields need to be included in this request or else the request will fail.

curl --request POST \
  --url <UPLOAD_URL> \
  --header 'Content-Type: multipart/form-data' \
  --form "key": "<key>",
  --form "policy": "<policy>",
  --form "x-goog-algorithm=GOOG4-RSA-SHA256",
  --form "x-goog-credential=intake-http@stairwell-prod.iam.gserviceaccount.com/20241120/auto/storage/goog4_request",
  --form "x-goog-date=20241120T202146Z",
  --form "x-goog-meta-asset-id=AAAAAA-BBBBBB-CCCCCC-DDDDDDDD",
  --form "x-goog-meta-file-detonate=DETONATION_PLAN_UNSPECIFIED",
  --form "x-goog-meta-file-format=RAW",
  --form "x-goog-meta-file-path=/home/test/filepath",
  --form "x-goog-meta-sha256=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  --form "x-goog-signature=67cfc4a5d1dd07adec819e309657bd6ac0c1b7db3a81822fdc3bad8342056cad3b928fa48db24bf3aeda9ff3afbc246c51274519c10d33e3720281e7ecdfcd1c85d33cf6c46b8448c14b0de473c9a73cd3a6e970ec5acf075617520a2b7c1216f1d9b0627b54bd28105e0db273a148acc3a196f16f2d7a82227b7369d850717a0d4724394d5e76d4ff26cc93c4a191ac738176447c17156e0312f67edb85eec30194da4534fea403c2cc731a6ffcaac188dc637d9273cfb33e0d573818044d481f00672edf70676dc6d3179850b3eca30a2f21073407b5d94b309e776bd0de2b149db3de4b59c1bd883b0d65195cf377c7c03fb8f1daa7259d4f0bccd155a812"
  --form 'file=@<YOUR_FILE_PATH>'

Replace values (like <UPLOAD_URL>, <YOUR_FILE_PATH>, etc.) with those from the preflight response.
After running this, the system responds with a success message (no content, just an HTTP status code 204).