> For the complete documentation index, see [llms.txt](https://doc.ozforensics.com/oz-knowledge/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.ozforensics.com/oz-knowledge/guides/administrator-guide/how-to-save-artifacts-to-s3-storage-using-instant-api.md).

# How to Save Artifacts to S3 Storage Using Instant API

### Overview

By default, Instant API (non-persistent mode) does not save any data anywhere – analysis results are returned immediately in the HTTP response, and nothing is stored. Starting from API 6.4.1, an optional feature allows saving analysis artifacts to external storage for debugging and incident investigation.

Instant API returns results to the client regardless of whether saving succeeds or fails – the saving process is isolated from the main analysis flow.

### What gets saved

When enabled, the following artifacts are saved per analysis request into a folder identified by `folder_id`:

<table data-header-hidden="false" data-header-sticky><thead><tr><th>File</th><th>Naming pattern</th><th>Description</th></tr></thead><tbody><tr><td>Container init data (for the container flow)</td><td><code>init_container.dat</code></td><td>Initial container data</td></tr><tr><td>Engine response</td><td><code>{source_media_id}_engine_response.json</code></td><td>Raw engine response (one file per analyzed media)</td></tr><tr><td>Request payload</td><td><code>payload.json</code></td><td>The original request body</td></tr><tr><td>API response</td><td><code>response.json</code></td><td>Full Instant API response (including <code>image_b64</code> for best shot and, starting from 6.6.1, action shot)</td></tr><tr><td><code>&#x3C;original_name></code></td><td>No pattern</td><td>Original media file name</td></tr></tbody></table>

Invalid containers (those that fail validation) are also saved.

{% hint style="info" %}
For Instant mode, `original_url` and `thumb_url` in the API response remain `null` even when saving is enabled. The saved data is a storage-only dump; there is no API endpoint to retrieve it.
{% endhint %}

### Configuration

#### Enabling the feature

Saving is disabled by default. To enable it, set [`OZ_INSTANT_SAVING_ARTIFACTS_ENABLED`](#user-content-fn-1)[^1] to `true` (default: `false`). When enabled, artifacts are saved according to the `OZ_FILE_STORAGE_TYPE` value (`LOCAL` or `S3`), not exclusively to S3.

#### Storage type

Example (S3 storage):

```shell
OZ_FILE_STORAGE_TYPE: "S3"
OZ_LOCAL_STORAGE_SUPPORT_ENABLE: "true"
OZ_S3_STORAGE_SUPPORT_ENABLE: "true"
```

* `OZ_FILE_STORAGE_TYPE` – `LOCAL` or `S3`. Determines where artifacts are written.
* `OZ_S3_STORAGE_SUPPORT_ENABLE` – must be set to `true` for S3 to work; derived from `OZ_FILE_STORAGE_TYPE`.
* `OZ_LOCAL_STORAGE_SUPPORT_ENABLE` – enables local storage support. On SaaS, both local and S3 support are enabled simultaneously, so this should be set to `true` as well.

For proper configuration, depending on the installation method that you use, refer to the documentation provided with installation package.

#### S3 connection parameters

{% hint style="info" %}
For `OZ_FILE_STORAGE_TYPE=S3`.
{% endhint %}

**Required**

| Parameter                   | Description                                            |
| --------------------------- | ------------------------------------------------------ |
| `OZ_STATIC_S3_BASE_URL`     | Base URL for constructing public links to static files |
| `OZ_STATIC_S3_BUCKET`       | S3 bucket name                                         |
| `OZ_STATIC_S3_ENDPOINT_URL` | S3 endpoint URL                                        |

**Optional**

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Parameter</th><th>Description</th><th>Default</th></tr></thead><tbody><tr><td><code>OZ_STATIC_S3_SUFFIX</code></td><td>Path prefix within the bucket</td><td><code>oz-media</code></td></tr><tr><td><code>OZ_STATIC_S3_BUCKET_URL</code></td><td>S3 bucket URL (can be left empty starting from 6.5.0)</td><td><code>""</code></td></tr><tr><td><code>OZ_STATIC_S3_ACCESS_KEY</code></td><td>S3 access key</td><td><code>None</code></td></tr><tr><td><code>OZ_STATIC_S3_SECRET_KEY</code></td><td>S3 secret key</td><td><code>None</code></td></tr><tr><td><code>OZ_STATIC_S3_REGION_NAME</code></td><td>AWS region name</td><td><code>None</code></td></tr></tbody></table>

#### Path formatting

* `OZ_MEDIA_STATIC_FOLDER_FORMAT` – `strftime` format for the date portion of the storage path (default: `%Y/%m/%d/%H`)

#### S3 bucket permissions

The following S3 actions are required for the IAM role or user accessing the bucket:

* `s3:ListBucket` (on the bucket resource)
* `s3:GetObject` (on objects within the bucket)
* `s3:PutObject` (on objects within the bucket)
* `s3:DeleteObject` (on objects within the bucket)

`ListBucket` is used during deletion: API lists all objects under the folder prefix, then deletes them individually. S3 has no native "delete folder" operation.

AWS IAM policy example:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListBucket",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
    },
    {
      "Sid": "ObjectOperations",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
    }
  ]
}
```

#### Authorization impact

* `OZ_AUTHORIZE_DISABLED_STATELESS` – when `true` (typical for Instant), `company_id` in the storage path is set to `00000000-0000-0000-0000-000000000000`. If `false`, `company_id` is taken from JWT.

#### Docker run example

```shell
sudo docker run -d -it \
  --name instant \
  -p 8081:8080 \
  -e OZ_INSTANT_SAVING_ARTIFACTS_ENABLED=true \
  -e OZ_STATIC_S3_SUFFIX=instant \
  -e OZ_STATIC_S3_BUCKET=<bucket> \
  -e OZ_STATIC_S3_ACCESS_KEY=<key> \
  -e OZ_STATIC_S3_SECRET_KEY=<secret> \
  -e OZ_STATIC_S3_ENDPOINT_URL=<endpoint_url> \
  -e OZ_STATIC_S3_BUCKET_URL=<bucket_url> \
  -e OZ_STATIC_S3_REGION_NAME=<region> \
  -e OZ_STATIC_S3_BASE_URL=<base_url> \
  -e OZ_FILE_STORAGE_TYPE=S3 \
  <api-instant-image>:<tag>
```

### Storage path

```
s3://{OZ_STATIC_S3_BUCKET}/{OZ_STATIC_S3_SUFFIX}/folders/{company_id}/{OZ_MEDIA_STATIC_FOLDER_FORMAT}/{folder_id}/
```

Where:

* `OZ_MEDIA_STATIC_FOLDER_FORMAT` defaults to `%Y/%m/%d/%H` (e.g., `2025/12/18/09`)
* `company_id` = `00000000-0000-0000-0000-000000000000`. When authorization is enabled (`OZ_AUTHORIZE_DISABLED_STATELESS=false`), `company_id` is taken from the authenticated user's company.

Example: `s3://{OZ_STATIC_S3_BUCKET}/{OZ_STATIC_S3_SUFFIX}/folders/00000000-0000-0000-0000-000000000000/2025/12/18/09/11111111-1111-1111-1111-111111111111/`

<details>

<summary>Path format in Full API (for reference)</summary>

In Full API mode, the database stores the full S3 path including bucket and suffix:

```
s3://{OZ_STATIC_S3_BUCKET}/{OZ_STATIC_S3_SUFFIX}/folders/11111111-.../2026/04/09/09/.../media_id.jpeg
```

In the API response, `s3://` is replaced with a public URL:

```
{PROTOCOL}://{API_HOSTNAME}/static/{OZ_STATIC_S3_BUCKET}/{OZ_STATIC_S3_SUFFIX}/folders/...
```

For local storage, the replacement becomes `{PROTOCOL}://{API_HOSTNAME}/static/`.

</details>

### Instant vs. Full API – comparison of storage behavior

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Aspect</th><th>Instant API</th><th>Full API</th></tr></thead><tbody><tr><td>Storage by default</td><td>Nothing is stored</td><td>All media and results stored in DB + file storage</td></tr><tr><td>Toggle required</td><td>Yes (<code>OZ_INSTANT_SAVING_ARTIFACTS_ENABLED</code>)</td><td>No (storage is a core function)</td></tr><tr><td>What is saved</td><td>media, payload, response, engine_response</td><td>media, analysis results, thumbnails, best shots, action shots</td></tr><tr><td><code>original_url</code> in response</td><td>Always <code>null</code></td><td>Public URL to static file</td></tr><tr><td><code>thumb_url</code> in response</td><td>Always <code>null</code></td><td>Public URL to thumbnail</td></tr><tr><td>DB records</td><td>None (stateless)</td><td>Full folder/media/analysis records</td></tr><tr><td>Storage path</td><td><code>s3://{OZ_STATIC_S3_BUCKET}/{OZ_STATIC_S3_SUFFIX}/folders/{company_id}/{OZ_MEDIA_STATIC_FOLDER_FORMAT}/{folder_id}/</code>; not returned to the client</td><td>Stored in DB as <code>s3://{OZ_STATIC_S3_BUCKET}/{OZ_STATIC_S3_SUFFIX}/folders/...</code>; resolved to <code>{PROTOCOL}://{API_HOSTNAME}/static/...</code> in the response</td></tr><tr><td>Data deletion via API</td><td>Not applicable</td><td><code>DELETE /api/folders/{id}</code> removes from DB and storage</td></tr></tbody></table>

[^1]: **For v6.5.0 and newer**;

    In 6.4.1, the parameter was called `OZ_INSTANT_SAVING_ARTIFACTS_IN_S3_ENABLED`


---

# 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://doc.ozforensics.com/oz-knowledge/guides/administrator-guide/how-to-save-artifacts-to-s3-storage-using-instant-api.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.
