MeetStream Guide: Custom S3 Storage
MeetStream Guide: Custom S3 Storage
By default, MeetStream stores all bot media — audio, video, transcripts, screenshots, chat logs, and meeting manifests — in its own S3 bucket, and serves them to you via presigned URLs when you call the fetch endpoints.
Custom S3 Storage lets you direct MeetStream to upload all of that media directly into your own S3 bucket using credentials you provide.
Use cases:
- Compliance or data-residency requirements (your data never leaves your AWS account).
- Direct integration with your own storage pipeline or data lake.
- Full control over file lifecycle, retention, and access policies.
1) Prerequisites
- An AWS S3 bucket in the region of your choice.
- An IAM user (or role) with credentials that grant at least write access (
s3:PutObject) to that bucket. If you also want MeetStream to serve the files back to you via its API, you’ll need to additionally grant read access (s3:GetObject). - A MeetStream API key.
Minimum IAM policy
Replace your-bucket-name with your bucket name.
If you also want the MeetStream API to serve presigned download URLs from your bucket (i.e. access_mode: "read_write"), add s3:GetObject to the same statement.
If you set a custom
prefix(see below), scope theResourceto that prefix instead — e.g.arn:aws:s3:::your-bucket-name/recordings/meetstream/*. If you use per-categoryprefixes, add oneResourceentry per distinct prefix (e.g..../recordings/audio/*,.../recordings/video/*, …).
2) Configure your S3 bucket
Parameters
Validation
For read_write, MeetStream performs a live HeadBucket check against your bucket before saving the configuration. If the credentials are invalid or the bucket doesn’t exist, the request will fail with a 400 error.
For write_only, MeetStream validates by writing a tiny probe object under each distinct prefix you configured ({prefix}/.write_probe_*, plus one per unique category prefix). This confirms your credentials can write without requiring read access, and works even if your IAM policy is scoped to those individual prefixes. If any probe write fails, the request returns a 400 error.
Response
Your
access_key_idandsecret_keyare stored securely and are never returned in any API response.
3) Access modes
Use write_only when:
- Your bucket is private and you want to control access yourself (generate your own presigned URLs).
- Your IAM policy only grants write permissions.
- You are piping files into your own processing pipeline and don’t need MeetStream to serve them.
If you start with
write_onlyand later upgrade toread_write, you can immediately use the fetch endpoints — no re-upload needed.
4) File layout in your bucket
MeetStream does not create a per-bot subfolder. Files are written directly into your configured prefix folder, with the bot id as a filename prefix ({prefix}/{bot_id}_<file>). This keeps each bot’s objects grouped by name while letting many bots share one folder. With the default prefix:
Or, with "prefix": "recordings/meetstream", the same files live under recordings/meetstream/abc123_....
Multi-file collections (
screenshots/, and transcript JSON undertranscription/<provider>/<id>/) keep a{bot_id}_<collection>/subfolder so their many files stay grouped — there is still no bare{bot_id}/folder.
Per-category prefixes
Each file belongs to one of four artifact categories, and you can route each category to its own top-level prefix via the prefixes object. Any category you don’t set inherits the base prefix.
For example, with "prefixes": {"audio": "recordings/audio", "video": "recordings/video", "transcript": "transcripts", "metadata": "metadata"}:
Prefixes isolate MeetStream files from any other objects in your bucket. You can change any prefix at any time; media written before a change remains fetchable at its original location (MeetStream records the exact bucket and key prefix used for each bot). New bots use the updated prefixes.
5) Fetching media after configuration
Once custom storage is configured, all subsequent bots write their media to your bucket. The MeetStream fetch endpoints work exactly the same as before — you do not need to change how you call them.
Fetch endpoints and URL behaviour
The 403 response for write_only includes a message indicating where the file lives:
6) Existing bots are not affected by configuration changes
Each bot’s media is pinned to whichever bucket was active when its files were written (after the bot leaves the meeting). Enabling, disabling, or changing custom storage will not affect media from bots that have already been processed — those files remain in the bucket they were originally written to.
7) View your current storage configuration
Returns your current storage configuration. Credential fields are never included in the response.
8) Delete your storage configuration
This removes your credentials and storage configuration. After deletion, new bots will have their media written to the MeetStream platform bucket.
Existing bots whose files were already written to your bucket are not affected — those files are not deleted from your bucket.
9) Troubleshooting
Configuration save fails with 400
- Confirm the bucket name and region are correct.
- Confirm the IAM credentials have
s3:PutObjectands3:GetObject(forread_write) on the bucket. - Confirm
access_modeis"read_write"if you want live validation.
Fetch endpoint returns 403 with "access_mode": "write_only"
- Your storage is configured as
write_only. Either access the file directly from your bucket, or update your configuration toread_write.
Fetch endpoint returns 404 for a bot that was processed
- The file may not have been written to your bucket due to a permissions error during upload. Check that your IAM credentials are valid and have
s3:PutObjectonarn:aws:s3:::your-bucket-name/meetstream/*(or your configured prefix, e.g.arn:aws:s3:::your-bucket-name/recordings/meetstream/*).
Presigned URL returns 403 Forbidden
- The URL may have expired — presigned URLs have a short lifetime (see the table in Section 5). Call the fetch endpoint again to get fresh URLs.
- Your IAM policy may not include
s3:GetObject. Update the policy and your storage configuration.
Bot was processed before I enabled custom storage — files are not in my bucket
- This is expected. Only bots processed after the configuration was saved write to your bucket. See Section 6.
