Skip to content

Object Storage

ZevCloud Storage is S3-compatible object storage. You create buckets, upload objects, and consume them from any tool that speaks S3 — boto3, the AWS SDK, aws-cli, rclone, whatever you already use. Pricing is in Naira, billed by plan, and bandwidth out of your buckets is included in the plan rather than billed separately.

Storage covers three common shapes of work:

If you want to…Use
Host file uploads from your app — profile pictures, document uploads, attachmentsA private bucket connected to your service
Serve static assets — images, video, downloads — at a public URLA public-read bucket (paid plan)
Back up databases, archive logs, store build artifacts from CIAny bucket, accessed from your CI or scripts with the bucket’s access key

You can mix all three on the same team. A typical setup might be a private bucket for an app’s uploads, a public bucket for a marketing site’s images, and a third bucket for nightly database backups.

  • A bucket is a flat container for objects. It has a name, a region, an access key pair, and a status (active, provisioning, error).
  • An object is a file. Every object has a key (its path within the bucket) and content.
  • Access keys are scoped to a single bucket. A leaked key on one bucket cannot read or write any other bucket. Each bucket has exactly one active key pair at a time.
  • A plan caps how much storage your team can hold across all buckets. The first plan is free. Paid plans unlock public buckets, custom domains, and larger caps.
  • A connected service is one of your app services that has been wired to a bucket via the dashboard’s Variables → Connect storage bucket action. The connection injects S3 environment variables into the service so your app code reads them directly.

S3-compatible API. Anything that speaks S3 works against your bucket. The four values your SDK needs — endpoint URL, region, bucket name, access key pair — all appear on the bucket detail page.

Per-bucket credentials. Each bucket has its own access key pair. Rotating the key shows the new secret once in the rotation response. The previous key keeps working for 24 hours after rotation so any services using it have time to pick up the new value.

Connect to a service in one click. From any of your app services, Variables → Connect storage bucket picks a bucket and injects five managed environment variables into the service: S3_ENDPOINT, S3_REGION, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY. Your app reads them with no extra config. When you rotate the bucket’s key, the connected service’s env vars update automatically.

Public-read buckets (paid plan). Mark a bucket public-read on create, and every object inside it is readable at a stable public URL with no signing required. Use for marketing assets, public downloads, or anything you want fetched from a browser.

Custom domains (paid plan). Attach your own hostname to a public-read bucket so files load at assets.yoursite.com instead of the default URL. Works with a domain you bought through ZevCloud (DNS configured automatically) or a domain hosted elsewhere (you set the CNAME).

Object Lock (WORM). Optional flag at bucket creation for compliance workloads where data must not be overwritten or deleted within a retention window. Once enabled, it cannot be turned off.

Built-in object browser. Every bucket has an Objects tab in the dashboard. Browse folders, upload, download, delete from the browser without installing any extra tool.

  1. Open the dashboard, click Storage in the left nav, then Create bucket.

  2. Give it a name (lowercase letters, digits, hyphens — same rules as S3) and pick a region.

    For a private bucket leave the Public read toggle off. For a bucket that serves files directly to browsers, turn it on. The toggle is only available on paid plans.

  3. Click Create. Within a few seconds the bucket lands in active status and a one-time secret access key appears on screen.

  4. Copy the secret access key now. It is shown once. The access key ID is visible later on the bucket detail page; the secret is not.

You can now use the bucket from any S3 client. Three of the most common paths follow.

Use the Connect storage bucket flow so the credentials land as environment variables and stay in sync with key rotations.

  1. Open the service in the dashboard. Click Variables.

  2. Click Connect storage bucket and pick the bucket.

  3. Five environment variables appear on the service: S3_ENDPOINT, S3_REGION, S3_BUCKET, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY. Marked as managed — you cannot edit them by hand; the values mirror whatever the bucket currently has.

  4. Redeploy the service so the runtime picks up the new env. Future key rotations are picked up automatically the next time the service restarts.

In your app code, read them as normal environment variables. Example using the AWS SDK for JavaScript:

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
const s3 = new S3Client({
endpoint: process.env.S3_ENDPOINT,
region: process.env.S3_REGION,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
},
// S3-compatible providers require path-style addressing.
forcePathStyle: true,
});
await s3.send(new PutObjectCommand({
Bucket: process.env.S3_BUCKET,
Key: 'uploads/profile.png',
Body: imageBuffer,
ContentType: 'image/png',
}));

The same shape works for boto3:

import os, boto3
s3 = boto3.client(
's3',
endpoint_url=os.environ['S3_ENDPOINT'],
region_name=os.environ['S3_REGION'],
aws_access_key_id=os.environ['S3_ACCESS_KEY_ID'],
aws_secret_access_key=os.environ['S3_SECRET_ACCESS_KEY'],
)
s3.upload_file('profile.png', os.environ['S3_BUCKET'], 'uploads/profile.png')

Grab the four values from the bucket detail page — endpoint, region, bucket name, access key ID — and the secret you copied at create time. Configure your tool of choice. Example with the AWS CLI:

aws configure --profile zevcloud
# AWS Access Key ID: <paste access key id>
# AWS Secret Access Key: <paste secret>
# Default region: <bucket region>
# Default output format: json
aws s3 ls s3://<bucket-name> \
--profile zevcloud \
--endpoint-url <bucket endpoint>

rclone, s3cmd, mc, and every cloud backup tool that takes “S3-compatible” credentials work the same way.

Open the bucket, click Objects. Drag and drop to upload, click any file to download, right-click to delete. Useful for one-off uploads, quick checks, or letting non-developer teammates manage files without sharing the access key.

  • The access key is bucket-scoped. It has no permissions on any other bucket on your team or on the platform. Leaking it limits the blast radius to the one bucket.
  • The secret access key is shown once at create time and again only at rotation time. The dashboard never re-displays it. If you lose it, rotate the key.
  • Owner and admin team roles can create buckets, fetch credentials, rotate keys, attach custom domains, and delete. Member role can browse object listings and download via presigned URLs but cannot fetch the raw access key.
  • Use separate buckets for separate concerns — one for user uploads, one for backups, one for public assets. The cost is the same and the blast radius is smaller.
  • Rotate the key anytime you suspect exposure. Old key keeps working for 24 hours so connected services have time to restart.

Storage is billed by plan, in Naira, monthly. Each plan caps how much storage your team can hold across all buckets. Bandwidth is included.

The dashboard shows your current usage against the cap. At about 80% used you’ll see a yellow notice; past the cap a red one. Writes continue to work past the cap — we don’t refuse uploads mid-form-submission — but the bill nudge becomes prominent and you should switch to a larger plan.

The first tier is free. See Plans & Pricing for current Naira amounts and per-plan caps.

After switching to a paid plan, if the corresponding invoice is not paid:

  • For about three weeks past due — storage is still fully writable. The dashboard shows a clear “past due” notice with a link to the unpaid invoice.
  • After about three weeks — storage goes read-only. Existing objects continue to serve; new uploads return an error.
  • After a further week — storage is terminated. Buckets and their objects are removed.

Pay the outstanding invoice at any point during the window and full access is restored immediately. Free-plan teams never enter this lifecycle since there is no invoice.

LimitDefaultNotes
Storage per teamCap on your current planSwitch plans to lift the cap
Buckets per teamNo hard limitSubject to your plan’s storage cap
Object sizeNo platform-imposed limitUse multipart upload for very large objects, same as standard S3
Public-read bucketsPaid plans onlyFree plan buckets are always private
Custom domains per bucketNo hard limitPaid plans only
Key rotation grace window24 hoursOld key keeps working for 24h after a rotation
Presigned URL max lifetime24 hoursDefault is 1 hour

Can I move objects from S3 (or any S3-compatible provider) into a ZevCloud bucket? Yes. Tools like rclone copy, aws s3 sync, and mc mirror work directly — point the source at your existing provider and the destination at your ZevCloud bucket using the endpoint/region/credentials from the detail page.

Can I use the same access key from multiple services? Yes, the access key is bucket-scoped, not service-scoped. Connecting the same bucket to two services injects the same managed env vars on both, and a rotation updates both automatically.

What happens to a bucket’s objects if I delete the bucket? The objects are removed with the bucket. Bucket deletion is irreversible; export anything you need first.

Can I make an existing private bucket public-read later? The flag is set at create time. To convert, create a new public-read bucket on a paid plan and copy the objects across with rclone or mc mirror.

What region should I pick? Pick the region closest to where your users or app services are. If you’re connecting the bucket to a service on ZevCloud, picking the same region the service runs in keeps the upload and download paths inside the same data centre.

  • Buckets walkthrough — creating buckets, choosing public vs private, connecting to services, attaching custom domains, rotating keys.
  • Storage API — every endpoint with request and response shapes for building against the API directly.
  • Plans & Pricing — current per-plan storage caps and Naira prices.