Your storage
Any storage that speaks S3.
Your parcels live in your own bucket. Set an endpoint and colis adjusts the two defaults S3-compatible providers expect; both stay overridable. The CLI writes a starter for each provider, and verifier tells you whether it actually works.
const store = createBucket({
bucket: 'livraisons',
endpoint: 'https://…', // set this, and two defaults follow:
// region: 'auto' // for providers that ignore the region
// forcePathStyle: true // https://endpoint/bucket/key
})Providers
Pick yours.
Not listed? Other S3-compatible storage works the same way: an endpoint, a key pair, and colis verifier to confirm the conditional writes are honoured. The CLI has the details.
Large files
One CORS rule, for uploads that skip the function.
Large files go from the browser straight to the bucket. The bucket has to allow `PUT` from your delivery page and let it read each answer’s `ETag`. Without the rule, small files keep working.
[
{
"AllowedOrigins": ["https://drop.example.com"],
"AllowedMethods": ["PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]On AWS S3, paste it under Permissions → Cross-origin resource sharing; the Cloudflare R2 dashboard takes the same JSON under the bucket’s settings. Add http://localhost:3400 to try it in development.
Send it. They sign off. You know.
Your storage, a delivery page under your name, a webhook at every step. Nothing hosted by someone else.