Usage & Quotas

Every project gets metered automatically. Uploads, downloads, and deletes flow through the event pipeline into daily rollups — no instrumentation required on your side.

What is metered

MetricCounted whenNotes
Upload bytesA file reaches uploaded statusSimple and multipart flows count once
Download bytesA download URL is issuedBandwidth quota is checked at this moment
Uploads / downloads / deletesPer operationShown as daily counts
Storage / file countEnd-of-day snapshotLive values come from the file index

Quotas

Four limits apply per project. Project overrides win; platform defaults apply otherwise:

  • Storage — total bytes across all non-deleted files (default 5 GiB)
  • File count — maximum number of files (default 10,000)
  • Max file size — per-file ceiling (matches the upload size limit)
  • Monthly bandwidth — download bytes per calendar month (default 10 GiB)

Exceeding a quota returns 403 with code QUOTA_EXCEEDED and details naming the quota, limit, current usage, and requested amount:

json
{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Project quota exceeded: storage_bytes (limit 5368709120, used 5368709110, requested 1024).",
    "details": {
      "quota": "storage_bytes",
      "limit": 5368709120,
      "used": 5368709110,
      "requested": 1024
    }
  }
}

A file larger than the per-file maximum returns 413 with code FILE_TOO_LARGE.

Querying usage

bash
curl -s https://api.apulodi.com/v1/usage \
  -H "Authorization: Bearer $APULODI_API_KEY"

Pass period (format YYYY-MM) for a previous month. The response contains the live quota snapshot, the period totals, and the daily series:

json
{
  "data": {
    "projectId": "prj_abc123",
    "period": "2026-09",
    "quotas": {
      "planTier": "free",
      "maxStorageBytes": 5368709120,
      "maxFileCount": 10000,
      "maxFileSizeBytes": 209715200,
      "monthlyBandwidthBytes": 10737418240
    },
    "storage": { "usedBytes": 1048576, "limitBytes": 5368709120 },
    "files": { "count": 3, "limit": 10000 },
    "bandwidth": { "usedBytes": 2048, "limitBytes": 10737418240 },
    "activity": {
      "uploads": 3,
      "downloads": 1,
      "deletes": 0,
      "uploadBytes": 1048576,
      "downloadBytes": 2048
    },
    "daily": [
      {
        "date": "2026-09-06",
        "uploadBytes": 1048576,
        "downloadBytes": 2048,
        "uploads": 3,
        "downloads": 1,
        "deletes": 0,
        "storageBytes": null,
        "fileCount": null
      }
    ]
  }
}

storageBytes and fileCount in the daily rows are end-of-day snapshots written by the daily sweep; they are null until the first sweep has run.

With the SDK

typescript
import { Apulodi } from "@apulodi/sdk";

const apulodi = new Apulodi({ apiKey: process.env.APULODI_API_KEY! });

const usage = await apulodi.usage.get();
console.log(usage.storage.usedBytes, "/", usage.storage.limitBytes);

// A specific month:
const august = await apulodi.usage.get("2026-08");

Managing quotas

Project admins can override limits in the dashboard under Project → Settings → Quota overrides, or via the dashboard API by patching maxStorageBytes, maxFileCount, maxFileSizeBytes, and monthlyBandwidthBytes on the project (send null to return to platform defaults). Changes apply immediately to new uploads and downloads.