S3 Bucket Delivery Reference

Learn how CloudZero ingests your custom cost data from S3 so you can structure your Adaptor's deliveries with confidence. The model is straightforward: each submission is the complete picture for a billing period, and CloudZero always reflects exactly what you send.

For setup instructions, see Connect via S3 Bucket.

How drops work

Each submission to your S3 bucket is called a drop. Ingestion follows this sequence:

  1. Your Adaptor (the script that converts and uploads your cost data) creates a drop inside your Bucket Path (an S3 key prefix, displayed as a folder in the console) containing CSVs with the complete data set for the billing period.
  2. Your Adaptor updates manifest.json to set current_drop_id to the new drop prefix. This is the only action that triggers ingestion.
  3. CloudZero polls the bucket, detects the manifest change, ingests every CSV in the referenced drop prefix, and replaces all previously ingested data for that billing period.
  4. Data appears in the Explorer. If validation fails, the connection status updates with details about the issue.

Full replacement in practice

Each drop must contain the complete data set for the billing period. The following example shows the correct pattern for a daily feed during May 2026 (billing period prefix 20260501-20260601).

May 12: First drop

cloudzero/                          # Bucket Path (set during connection setup)
  20260501-20260601/                # billing period prefix
    drop-day-12/                    # drop prefix
      cost_data_2026-05-12.csv.gz   # cost data (CBF format, gzipped)
    manifest.json                   # points to the active drop prefix
{
  ...
  "current_drop_id": "drop-day-12"
  ...
}

Manifest points to: drop-day-12
Drop contains: cost_data_2026-05-12.csv.gz
Days removed from CloudZero by this drop: None
Days added to CloudZero by this drop: May 12

May 13

20260501-20260601/
  drop-day-12/
    # unchanged
  drop-day-13/
    cost_data_2026-05-12.csv.gz
    cost_data_2026-05-13.csv.gz
  manifest.json
{
  ...
  "current_drop_id": "drop-day-13"
  ...
}

Manifest points to: drop-day-13
Drop contains: cost_data_2026-05-12.csv.gz and cost_data_2026-05-13.csv.gz.
Days removed from CloudZero by this drop: None
Days added to CloudZero by this drop: May 12, May 13

May 14

20260501-20260601/
  drop-day-12/
    # unchanged
  drop-day-13/
    # unchanged
  drop-day-14/
    cost_data_2026-05-12.csv.gz
    cost_data_2026-05-13.csv.gz
    cost_data_2026-05-14.csv.gz
  manifest.json
{
  ...
  "current_drop_id": "drop-day-14"
  ...
}

Manifest points to: drop-day-14
Drop contains: cost_data_2026-05-12.csv.gz, cost_data_2026-05-13.csv.gz, and cost_data_2026-05-14.csv.gz.
Days removed from CloudZero by this drop: None
Days added to CloudZero by this drop: May 12, May 13, May 14

May 15: Incomplete drop

The following example shows what happens when a drop does not include the complete data set.

20260501-20260601/
  drop-day-14/
    # unchanged
  drop-day-15/
    cost_data_2026-05-15.csv.gz
  manifest.json
{
  ...
  "current_drop_id": "drop-day-15"
  ...
}

Manifest points to: drop-day-15
Drop contains: Only cost_data_2026-05-15.csv.gz.
Days removed from CloudZero by this drop: May 12, May 13, May 14. The earlier CSVs are still in previous drop prefixes but are not included in this drop.
Days added to CloudZero by this drop: May 15

May 16: Complete drop restores the full period

The next drop includes all days again, restoring the complete data set.

20260501-20260601/
  drop-day-15/
    # unchanged
  drop-day-16/
    cost_data_2026-05-12.csv.gz
    cost_data_2026-05-13.csv.gz
    cost_data_2026-05-14.csv.gz
    cost_data_2026-05-15.csv.gz
    cost_data_2026-05-16.csv.gz
  manifest.json
{
  ...
  "current_drop_id": "drop-day-16"
  ...
}

Manifest points to: drop-day-16
Drop contains: cost_data_2026-05-12.csv.gz, cost_data_2026-05-13.csv.gz, cost_data_2026-05-14.csv.gz, cost_data_2026-05-15.csv.gz, and cost_data_2026-05-16.csv.gz.
Days removed from CloudZero by this drop: None
Days added to CloudZero by this drop: May 12, May 13, May 14, May 15, May 16. The complete data set is restored.

File and prefix reference

This section covers the files your Adaptor creates, where they go in S3, and how each component fits together.

Files in a drop

Each drop involves two things: one or more CSV files uploaded to a drop prefix, and an update to the manifest.json in the billing period prefix.

FileLocationFormatPurpose
CSV files (one or more)Inside the drop prefixCommon Bill Format (CBF), gzipped, UTF-8, 1,000,000 rows max per file. Split larger data sets across multiple files in the same drop.Cost data for the billing period
manifest.jsonIn the billing period prefix (alongside the drop prefixes)JSON, one per billing periodPointer to the active drop

Set the pointer with manifest.json

The manifest is how your Adaptor tells CloudZero that new data is ready. CloudZero reads the manifest to find out which drop prefix to ingest. Your Adaptor updates the manifest after every drop; CloudZero does the rest.

Each billing period has exactly one manifest, located at <bucket_path>/<billing_data_id>/manifest.json.

{
  "version": "1.3.0",
  "current_drop_id": "20260514T120000Z"
}
FieldDescription
versionManifest schema version. Currently 1.3.0.
current_drop_idThe drop prefix CloudZero uses for this billing period. When this value changes, CloudZero ingests the referenced drop.

S3 bucket and prefix structure

Your bucket organizes data into three levels: your Bucket Path (set during connection setup), a billing period for each month, and a drop for each delivery within that month. In S3, each level is a key prefix displayed as a folder in the console.

<bucket_path>/
  <billing_data_id>/
    <drop_id_1>/
      cost_data_2026-05-12.csv.gz
    <drop_id_2>/
      cost_data_2026-05-12.csv.gz
      cost_data_2026-05-13.csv.gz
    manifest.json
ComponentFormatDescription
<bucket_path>The Bucket Path you entered during connection setupAn S3 key prefix inside the bucket. Not the bucket root.
<billing_data_id>YYYYMMDD-YYYYMMDDOne prefix per billing month. May 2026 is 20260501-20260601.
<drop_id>Any unique stringA unique identifier for each drop. Recommended: an ISO timestamp such as 20260520T154516Z.
CSV files*.csv.gzOne or more gzipped CBF files per drop.

Choose a delivery pattern

Your Adaptor can structure daily feeds in two ways. Both deliver the same data to CloudZero and produce identical spend throughout the platform.

Pattern A: One CSV per day, carried forward

Each drop contains a separate CSV for every day in the billing period so far. On day 14, the drop has 14 objects:

drop-day-14/
  cost_data_2026-05-01.csv.gz
  cost_data_2026-05-02.csv.gz
  ...
  cost_data_2026-05-14.csv.gz

Tradeoff: More objects per drop as the month progresses, but each day's source data is individually accessible in S3 for auditing, backups, and debugging your Adaptor.

Pattern B: Single cumulative CSV

Each drop contains one CSV with all rows for the billing period so far. On day 14, the drop has one object:

drop-day-14/
  cost_data_month_to_date.csv.gz

Tradeoff: One object per drop regardless of how far into the month you are, but viewing a single day's data requires filtering in Explorer or AI Hub.

Monitor connection status with Health Check Interval

When you create your connection, you can set a Health Check Interval, in Hours. This tells CloudZero how long to wait between drops before flagging the connection as unhealthy. It does not affect how CloudZero ingests your data.

Set this value higher than your Adaptor's delivery schedule so normal timing variations do not trigger a false failure:

Drop cadenceRecommended setting
Multiple drops per day6 to 12 hours
Daily24 to 48 hours
Less than dailyA value greater than the slowest expected interval

Managing old drops

CloudZero only reads the drop prefix that the manifest points to. Previous drops stay in your bucket but have no effect on what CloudZero displays. You can keep them for auditing or to revert to a previous drop by updating current_drop_id, or delete them when you no longer need them.

💡

A common approach is to keep the most recent 2 to 3 drops and automatically remove older ones using an S3 lifecycle rule once the month ends.

Updating and clearing data

Because each drop fully replaces the billing period's data in CloudZero, you manage your data by controlling what goes into the next drop.

ActionHow
Update or correct recordsInclude the corrected records alongside all other records for that billing period in your next drop.
Remove specific recordsInclude all records for the period except the ones you want to remove in your next drop.
Clear an entire billing periodCreate a drop containing a CSV with only the header row and no data rows, then update current_drop_id to that drop. This is useful when you need to re-baseline a month or remove test data before sending production records.
Change the S3 bucketCreate a new connection and pause (not delete) the old one. This preserves historical data.

Troubleshooting

SymptomCauseResolution
Data is missing or only the most recent day appears in ExplorerThe active drop does not contain the complete set of CSVs for the billing periodCreate a new drop containing every CSV for the period and update the manifest. CloudZero reflects the new drop on the next poll cycle.
No data updates despite new objects in the bucketmanifest.json was not updatedUpdate current_drop_id to point to the new drop prefix
Connection shows a health check failure on a daily feedHealth Check Interval is set below the drop cadenceRaise the value to 24 or 48 hours
Manifest was updated but data has not changed yetCloudZero has not polled the bucket since the updateCloudZero polls on a regular interval. Data appears after the next poll cycle completes.
ℹ️

Have questions or feedback? Reach out to your account manager.