Connect via REST API

The REST API method sends cost data to CloudZero in JSON format. This is the recommended connection method for Custom Cost Data Sources.

This guide covers creating the connection in CloudZero and writing the Adaptor that converts and sends your data.

What you need

  • Permission to create connections in CloudZero
  • A CloudZero API key with the following scopes:
    • connections:create_billing_anycost_billing_drop
    • connections:create_billing_anycost_validate_billing_drop
    • connections:read_billing_anycost_billing_drops
    • connections:read_billing_anycost_billing_drops_month
  • Access to your source's cost data (via API, export, database, or other method)

Step 1: Create the connection in CloudZero

  1. In CloudZero, go to Settings > Cloud Connections.
  2. Select Create Connection +.
  3. Select Custom, then select the REST API tile.
  4. Enter a Connection Name to identify the billing source. This is typically the main account or billing account that the service sends the bill from (for example, simple-cloud-main). The name cannot contain spaces, periods, or special characters except hyphens and underscores.
  5. Enter the Cloud Provider name. This label appears in the Cloud Provider Dimension and throughout the CloudZero UI (for example, Simple Cloud).
  6. Select Save.
  7. Select your connection from the Billing Connections table and copy the Connection ID. You need this in your Adaptor to send data to the API.

Your connection appears in the Billing Connections table with a status of Pending Data until CloudZero receives your first submission.

Step 2: Write your Adaptor

An Adaptor is a script that retrieves cost data from your source, converts it to Common Bill Format (CBF), and sends it to CloudZero's API. You can write it in any programming language. Use appropriate numeric data types for cost values (for example, decimal.Decimal instead of float in Python).

Your Adaptor needs to handle four things:

  1. Identify your source's cost data. Refer to your vendor's documentation or support to find where they provide billing or usage data. You need either a total cost for a given period, or usage data you can convert into a cost based on your rate.

  2. Identify how to retrieve that data. Determine how your source lets you export or access the data: an API, a CSV download, a database query, or another method. This determines how your script retrieves data for each billing month. Your Adaptor should also support reprocessing previous months, since your source can retroactively adjust billing data through reconciliations, credits, or corrections.

  3. Convert the data to Common Bill Format. Map each record from your source's format to CBF fields:

    • At minimum, each record needs a cost amount (cost/cost) and a date (time/usage_start).
    • Add context fields (service, account, region) for richer breakdowns in CloudZero.
    • Preserve the granularity of your source data. If your source provides hourly data, do not aggregate it to daily.
    • Amortize costs to hourly granularity when possible. Data is viewable in CloudZero at the lowest granularity you provide.
    • Include all charge types your source provides: usage, taxes, discounts, and committed use charges.

    For example, if your source provides a record like this:

    date: "2024-08-16"
    service: "Compute"
    amount: 12.00
    account: "prod-001"

    Your Adaptor maps it to CBF:

    time/usage_start: "2024-08-16T00:00:00Z"
    resource/service: "Compute"
    cost/cost: 12.00
    resource/account: "prod-001"
    lineitem/type: "Usage"
  4. Send the data to CloudZero's API. Your Adaptor sends the converted data as a JSON request body to the AnyCost Stream API:

    POST /v2/connections/billing/anycost/{connection_id}/billing_drops

    Replace {connection_id} with the Connection ID from Step 1. See the API reference for authentication details.

    The request body contains three elements:

    ParameterRequiredDescription
    monthYesThe billing month in ISO 8601 format (for example, 2024-08). All records must be from the same month.
    operationNoHow CloudZero handles existing data for this month. Default: replace_drop. See Operation types.
    dataYesAn array of JSON objects, one per line item, with CBF column names as keys. All records for the billing month are sent together in a single request body.

    Submit on a schedule that matches when your source provides new data. Each submission has a processing cost, so avoid submitting more frequently than your source produces meaningful updates.

⚠️

CloudZero replaces all existing data for a billing month each time you submit. Every submission must include all records for the month, not just new or changed records. If your source provides only incremental data (for example, just today's records), your Adaptor must store previous records and combine them with new ones before sending.

Pseudocode

function process_month(year_month):
    records = retrieve_cost_data(source, year_month)

    if source_provides_incremental_data:
        previous = load_previous_records(year_month)
        records = merge(previous, records)
        save_records(records, year_month)

    cbf_data = []
    for record in records:
        cbf_data.append({
            "time/usage_start": to_iso8601_utc(record.date),
            "cost/cost": record.amount,
            "resource/service": record.service,
            "resource/account": record.account,
            "lineitem/type": "Usage"
        })

    send_to_cloudzero(connection_id, year_month, cbf_data)

For a complete working implementation in Python, see the CloudZero AnyCost Example on GitHub.

Operation types

The operation parameter controls how CloudZero handles existing data for the specified month:

OperationBehavior
replace_drop (default)Replaces all existing data for the month. Your request must include every record for the full month.
replace_hourlyReplaces only the hours that overlap with your submission. You can send a partial month.
sumAppends records to existing data. You can send a partial month.

If no data exists for the specified month, CloudZero creates a new billing drop regardless of the operation type.

API limits

LimitValue
Request body size5MB (uncompressed JSON)
Concurrent requestsOne request at a time per connection
Monthly data per connection1 million rows and 400MB total

What to expect

After your first submission, CloudZero validates and processes the data. The connection status changes from Pending Data to Healthy, and your cost data appears in the Explorer. This can take up to 24 hours.

If your Adaptor sends data incorrectly or the CBF format has errors, the connection status updates with details about the issue.

Maintaining your data

CloudZero ingests data cumulatively. Each submission for a billing month replaces all previous data for that month. Use this behavior to manage your data:

ActionHow
Update recordsInclude the corrected records alongside all other records for that month in your next submission.
Delete specific recordsSubmit all records for that month except the ones you want to remove.
ℹ️

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