Skip to content

Stash API

The purpose of Stash is to provide a simple interface for storing your application's files via Amazon S3.

Authentication / Authorization

To authenticate with Stash, pass your client credentials using the Basic Authentication scheme Authorization: Basic <base64_encoded_credentials>.

To request your new Client ID and Client Secret credentials, please reach out to the Enterprise Applications team via email at its-ais-enterprise-apps@uiowa.edu. Existing clients can use your current Client ID but you will be assigned a new Client Secret.

Hosts

Production: https://stash.its.uiowa.edu

Test: https://stash-test.its.uiowa.edu

Library Support

The following libraries are written and maintained for Java developers. Follow the links below for up-to-date usage and release information.

Java 21 + Springboot Library

Java 8 Library

Upload a File

Upload a file to S3 and optionally specify filename, expiration, and metadata

Request URL

http
POST    /api/v1/files/upload

Request Body

Uploads should be encoded as multipart/form-data using the names file and meta for the file and data parts respectively.

The meta portion of the request is optional and consists of JSON with the following attributes.

  • filename - An optional attribute allowing clients to override the original name of the multipart-upload.

  • expiresIn - Optional duration after which the file upload will expire and become inaccessible. The expiration date will be set as a positive duration offset from the upload date. Negative values will result in an error.

  • metadata - A simple map of key/value pairs optionally used to identify/categorize your data. Api Clients should consider limiting the amount of metadata stored in Stash as it is not meant to be used as a database.

Duration Format

This supports both the ISO-8601 standard and a simple formats shown below. Defaults to seconds if no unit is specified.

Simple format:

  • ns for nanoseconds
  • us for microseconds
  • ms for milliseconds
  • s for seconds
  • m for minutes
  • h for hours
  • d for days

Non-Production Automatic Expiration

In non-prod environments file assets are set to automatically expire in 30 days.

Example: File upload with metadata and 10 minute expiration

Upon successful upload, your application should store the value of the uuid attribute for later reference. Note in the example below, we've set the name to admissions_supp_hawkid.txt to override the original name provided by the uploader.

http
POST    /api/v1/files/upload

Content-Type: multipart/form-data; boundary=1234567890

--1234567890

Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

This is a sample file.

--1234567890

Content-Disposition: form-data; name="meta"; 
Content-Type: application/json
{
    "filename": "standardized.txt",
    "expiresIn": "10m",
    "metadata": {
        "category": "SIMPLE"
    }
}

--1234567890--
json
{
    "uuid": "26d9d41a-347a-4b72-9aa5-ad1eeb67272c",
    "filename": "standardized.txt",
    "fileSize": 22,
    "contentType": "text/plain",
    "uploadDate": "2025-07-28T09:33:02.618756",
    "expirationDate": "2025-07-28T09:43:02.618756",
    "metadata": {
        "category": "SIMPLE"
    }
}

Download via presigned URL

Get a temporary presigned URL for downloading or sharing. This is the preferred method of downloading as the file transfer is coordinated directly with AWS rather than Stash processing the download as well.

Authorization

A Presign URL is public, therefore, it is your application's responsibility for providing any sort of custom authorization layer to restrict access.

Request URL

http
GET     /api/v1/files/{uuid}/presign

Request Parameters

inline - Optional boolean indicating whether you'd prefer the content-disposition header be specified as inline or attachment. Defaults to attachment.

expiresIn - Optional duration indicating how long the presign url is accessible. The expiration time can be set between 1 second and 7 days. Other values will result in error.

Duration Format

This supports both the ISO-8601 standard and a simple formats shown below. Defaults to seconds if no unit is specified.

Simple format:

  • ns for nanoseconds
  • us for microseconds
  • ms for milliseconds
  • s for seconds
  • m for minutes
  • h for hours
  • d for days

Example

http
GET     /api/v1/files/26d9d41a-347a-4b72-9aa5-ad1eeb67272c/presign
json

https://ais-entapps-stash-dev.s3.amazonaws.com/dev_app/2025/26d9d41a-347a-4b72-9aa5-ad1eeb67272c...

View File Asset Meta

Get information about the current state of a file asset

Request URL

http
GET     /api/v1/files/{uuid}/meta

Example

http
GET     /api/v1/files/26d9d41a-347a-4b72-9aa5-ad1eeb67272c/meta
json
{
    "uuid": "26d9d41a-347a-4b72-9aa5-ad1eeb67272c",
    "filename": "standardized.txt",
    "fileSize": 22,
    "contentType": "text/plain",
    "uploadDate": "2025-07-28T09:33:02.618756",
    "expirationDate": "2025-07-28T09:43:02.617212",
    "metadata": {
        "category": "SIMPLE"
    }
}

Update File Asset Meta

Update information about a file asset including filename, expiration, and metadata

Request URL

http
PUT     /api/v1/files/{uuid}/meta

Request Body

filename - The name will only be updated if the value is non-blank. Otherwise, the property is ignored.

expiresIn - The expiration date will be set as a positive duration offset from the upload date. Negative values will result in an error. To clear a previously set expiration, the client should send a duration of zero.

metadata Updates are handled as follows:

  • Key passed with a non-null value will be added/updated
  • Key passed with a value of null or empty string will be removed from the existing metadata map
  • Keys that are omitted from existing metadata map will be ignored

Example

http
PUT     /api/v1/files/26d9d41a-347a-4b72-9aa5-ad1eeb67272c/meta
json
{
    "filename": "standardized_v2.txt",
    "expiresIn": "20m",
    "metadata": {
        "category": null,
        "category_2": "EXTREME"
    }
}
json
{
    "uuid": "26d9d41a-347a-4b72-9aa5-ad1eeb67272c",
    "filename": "standardized_v2.txt",
    "fileSize": 22,
    "contentType": "text/plain",
    "uploadDate": "2025-07-28T09:24:34.012119",
    "expirationDate": "2025-07-28T09:44:34.012119",
    "metadata": {
        "category_2": "EXTREME"
    }
}

Delete File Asset

Delete a file asset

Note: File asset deletion is a soft operation. The asset becomes immediately inaccessible via the API, but the object itself will remain in the S3/Backups and is subject to current lifecycle configurations.

Request URL

http
DELETE     /api/v1/files/{uuid}

Example

http
DELETE     /api/v1/files/26d9d41a-347a-4b72-9aa5-ad1eeb67272c
http
204 No Content

Create Share

Grant another client access to a specific file asset.

Shares come in two forms:

  • SINGLE_FILE — shares access to a single specific file asset. This is the standard sharing method available to all API clients.
  • ALL_FILES — grants the grantee access to all files you own, including any you upload in the future. This type of share can only be configured by an administrator through the admin interface.

Share Validations

  • Creating a SINGLE_FILE share when an ALL_FILES share already exists with that grantee returns 400.
  • Creating an ALL_FILES share (admin only) when SINGLE_FILE shares already exist with that grantee returns 400.

To switch sharing styles, you must revoke the existing shares first. Reach out to Stash support if this situation arises.

Request URL

http
POST    /api/v1/shares

Request Body

  • granteeClientId - Required. The client ID of the application being granted access.

  • fileAssetUuid - Required. The UUID of the specific file asset to share.

Example: Share a specific file asset

http
POST    /api/v1/shares
Content-Type: application/json

{
    "granteeClientId": "other-app-client-id",
    "fileAssetUuid": "26d9d41a-347a-4b72-9aa5-ad1eeb67272c"
}
json
{
    "ownerClientId": "my-app-client-id",
    "granteeClientId": "other-app-client-id",
    "fileAssetUuid": "26d9d41a-347a-4b72-9aa5-ad1eeb67272c",
    "type": "SINGLE_FILE",
    "createdAt": "2025-07-28T09:33:02"
}

List Shares

List active shares granted by the authenticated client.

Request URL

http
GET    /api/v1/shares

Request Parameters

  • page - Optional. Zero-based page index. Defaults to 0.

  • size - Optional. Number of results per page. Defaults to 20.

  • sort - Optional. Sort expression in the format property,direction (e.g., createdAt,desc).

  • granteeClientId - Optional. Filter results to shares for a specific grantee client.

  • fileAssetUuid - Optional. Filter results to shares covering a specific file asset. When provided, both SINGLE_FILE shares for that file and any ALL_FILES shares are returned, since an ALL_FILES share implicitly covers every file.

Example

http
GET    /api/v1/shares?page=0&size=20&sort=createdAt,desc
json
{
    "content": [
        {
            "ownerClientId": "my-app-client-id",
            "granteeClientId": "other-app-client-id",
            "fileAssetUuid": "26d9d41a-347a-4b72-9aa5-ad1eeb67272c",
            "type": "SINGLE_FILE",
            "createdAt": "2025-07-28T09:33:02"
        },
        {
            "ownerClientId": "my-app-client-id",
            "granteeClientId": "another-client-id",
            "fileAssetUuid": null,
            "type": "ALL_FILES",
            "createdAt": "2025-07-27T14:10:45"
        }
    ],
    "page": {
        "totalElements": 2,
        "totalPages": 1,
        "number": 0,
        "size": 20
    }
}

Revoke Share

Revoke a SINGLE_FILE share for a specific grantee and file asset.

Request URL

http
DELETE    /api/v1/shares/{granteeClientId}

Request Parameters

  • fileAssetUuid - Required. The UUID of the file asset share to revoke.

Example

http
DELETE    /api/v1/shares/other-app-client-id?fileAssetUuid=26d9d41a-347a-4b72-9aa5-ad1eeb67272c
http
204 No Content

Errors

Stash implements the "Problem Details" specification, RFC7807, for reporting of HTTP request errors in a consistent JSON format. You can expect unsuccessful API requests to look like the examples below.

Example: A presign download request for a file asset that has expired

json
{
    "status": 400,
    "title": "Bad Request",
    "detail": "The requested file asset is expired",
    "instance": "/api/v1/files/26d9d41a-347a-4b72-9aa5-ad1eeb67272c/presign",
    "type": "https://docs.ais.its.uiowa.edu/stash/api.html#errors"
}