Skip to main content

Overview

Uplint stores every accepted file in your own Amazon S3, using credentials you provide. A storage bucket (also called a storage configuration) bundles the S3 details Uplint needs to read and write objects on your behalf:
  • The bucket name and AWS region
  • An access key ID and secret access key (encrypted at rest, never returned)
  • A base path prefix applied to every object written to the bucket
  • A human-friendly name used to identify the bucket in the dashboard and API
A tenant can register many buckets. One of them is always the default (fallback) bucket, and each file context can be routed to any active bucket you choose. This lets you keep, say, patient documents, avatars, and exports in separate buckets — each with its own credentials, region, and lifecycle — while still driving everything through one Uplint API.
All storage bucket endpoints require an API key with the admin scope. Managing storage is an administrative operation, distinct from the upload/download scopes used for day-to-day file traffic.

Why multiple buckets?

A single bucket works fine when everything you ingest belongs together. Multiple buckets become useful when different kinds of uploads have different requirements:

Data separation

Keep regulated data (e.g. medical claims) in a dedicated bucket, isolated from lower-sensitivity uploads like profile photos.

Data residency

Route EU uploads to an eu-west-1 bucket and APAC uploads to ap-south-1 to satisfy residency requirements.

Independent credentials

Give each bucket its own IAM key so you can rotate or revoke access for one workload without touching the others.

Cost & lifecycle

Apply different S3 lifecycle and storage-class policies per bucket, matched to how long each data type must live.

The default bucket

Exactly one bucket is the tenant’s default at any time. The default is the fallback Uplint uses whenever a more specific bucket can’t be determined — for example, when a file context isn’t bound to a bucket.
  • The first bucket you add automatically becomes the default.
  • Create a bucket with set_as_default: true to make it the default on creation.
  • Promote an existing bucket at any time with the Set Default Bucket endpoint. Promoting one bucket demotes the previous default.
  • The default bucket can’t be deleted. Set a different default first.

Routing: which bucket a file goes to

Every file context has an optional storage_config_id. That single field decides where a context’s uploads land.

On upload

When a file is uploaded into a context, Uplint resolves the target bucket in this order:
  1. The context’s storage_config_id, if it points to an active bucket.
  2. Otherwise — unset, missing, or inactive — the tenant’s default bucket.
Binding a context to a bucket is just setting storage_config_id on the context. Send an empty string when updating a context to unbind it and fall back to the default bucket.

On download

Uplint records which bucket each file was written to, so files remain readable even after you add, rename, or re-route buckets. When serving a download it resolves the bucket in this order:
  1. The file’s stored storage_config_id.
  2. Otherwise, a bucket whose name matches the one recorded on the file (this keeps files uploaded before multi-bucket routing readable).
  3. Otherwise, the tenant’s default bucket.
Because routing is resolved per file, re-pointing a context to a different bucket only affects new uploads. Existing files keep resolving to the bucket they were originally written to.

Immutable fields

Once a bucket is created, its default_bucket (the S3 bucket name) and base_path cannot be changed — doing so would orphan every file already stored under them. To move data to a different bucket or prefix, add a new storage bucket and route your contexts to it. You can always update the safe fields:

Credential handling

Secret access keys are encrypted at rest and are never returned by any endpoint. When you read a bucket, the access_key_id comes back masked (e.g. AKIA...MPLE) so you can recognize which key is in use without exposing it. To change a key, submit a new access_key_id and secret_access_key via Update Storage Bucket.

Deleting a bucket

Deletion is refused when the bucket is either:
  • the tenant’s default bucket, or
  • still bound to one or more file contexts.
Reassign or unbind those contexts (and, if needed, promote another bucket to default) before deleting. This guard prevents accidentally cutting off the storage that live contexts depend on.

Worked example

Register a dedicated bucket for insurance claims, then route a context to it.
1

Add the bucket

The response returns a config_id (e.g. cfg_a1b2c3d4e5f6). The access key comes back masked and the secret is omitted.
2

Route a context to it

New uploads into insurance_claims now land in acme-insurance-claims. Every other context continues to use whatever bucket it was routed to, or the default.
3

(Optional) Make it the default

Backward compatibility

Multi-bucket routing is fully backward compatible. Tenants that already had a single storage configuration keep working with zero changes: their existing config becomes the default bucket, and files uploaded before routing existed continue to resolve by their recorded bucket name. You only opt into multiple buckets when you add a second one.

API reference

List storage buckets

Every bucket configured for the tenant.

Add a storage bucket

Register a new S3 bucket.

Get a storage bucket

Fetch a single bucket by ID.

Update a storage bucket

Rotate keys, rename, or toggle active.

Set default bucket

Choose the tenant’s fallback bucket.

Delete a storage bucket

Remove an unused bucket.