Reference
Storage (S3 / R2 / MinIO)
Configure where attachments, knowledge documents, and assets are stored.
AskAIs Customer Service talks to any S3-compatible object store. Switch providers by editing a few .env variables — code is identical. Below: AWS S3, Cloudflare R2, and self-hosted MinIO.
What gets stored
- Message attachments (images, video, PDFs, etc.) uploaded by visitors or agents
- Knowledge base source documents (for RAG ingestion)
- Object key template:
tenants/{tenantId}/yyyy/mm/{uuid}.{ext}
Cloudflare R2 (recommended for self-host)
R2 has zero egress fees — perfect if you serve attachments to many users. Get your access key + secret from R2 dashboard → Manage R2 API Tokens.
# .env
S3_ENDPOINT="https://<account-id>.r2.cloudflarestorage.com"
S3_REGION="auto"
S3_BUCKET="singlink"
S3_ACCESS_KEY="..."
S3_SECRET_KEY="..."
# Public URL for the bucket (custom domain pointing to R2 public access)
S3_PUBLIC_URL="https://files.acme.com"To get a public URL, enable Public access on the bucket and bind a custom subdomain (R2 dashboard → bucket → Settings → Custom Domains).
AWS S3
S3_ENDPOINT="" # leave empty for AWS
S3_REGION="us-east-1"
S3_BUCKET="singlink-prod"
S3_ACCESS_KEY="AKIA..."
S3_SECRET_KEY="..."
S3_PUBLIC_URL="https://singlink-prod.s3.amazonaws.com"Bucket policy must allow s3:PutObject for the access key, plus public read if you want unauthenticated downloads. Otherwise we'll fall back to presigned GET URLs on every read.
MinIO (default for local dev)
S3_ENDPOINT="http://localhost:9002"
S3_REGION="us-east-1"
S3_BUCKET="singlink"
S3_ACCESS_KEY="minio"
S3_SECRET_KEY="minio_dev_password"
S3_PUBLIC_URL="http://localhost:9002/singlink"Backblaze B2 (cheap S3 alternative)
S3_ENDPOINT="https://s3.us-west-001.backblazeb2.com"
S3_REGION="us-west-001"
S3_BUCKET="singlink"
S3_ACCESS_KEY="..."
S3_SECRET_KEY="..."Caveats
- CORS — bucket needs to allow
POSTfrom your widget's host. Most providers default to wildcard; for R2 explicitly set CORS rules via the API. - Region
autoonly works for R2. AWS / B2 want a real region name. - S3_PUBLIC_URL — if empty, the SDK constructs URLs from
S3_ENDPOINT + bucket. Set explicitly when behind a CDN or custom domain.