メインコンテンツへスキップ

ingest-datahub-events-csv

dci ingest-datahub-events-csv [body]

Sends a batch of events to DataHub using a CSV file, either uncompressed or compressed in ZIP or GZ format. It may take up to 15 minutes for the data to become available in the DoiT console.

Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.

Before you upload

provider is the dataset name (dci list-datahub-datasets); create it first with dci create-datahub-dataset name: <dataset> if it does not exist. The CSV must follow the dataset's schema template. For the Default template the header row is usage_date[,id],<dimension>...,<metric>... with RFC 3339 UTC timestamps; see CSV ingestion. Requires the DataHub Admin permission. Rows appear in Cloud Analytics within about 15 minutes.

Undo a bad upload

There is no delete-by-batch API. Remove the rows with dci delete-datahub-events-by-filter using the time range the file covered, then upload the corrected file.

Examples

# Upload a CSV into the dataset `litellm-usage`; the `@` attaches the file and keeps its name.
dci ingest-datahub-events-csv provider: litellm-usage, file: @events.csv
batch batchId generatedEvents ingestedRows provider
csv_events.csv_1756987200000 csv_events.csv_1756987200000 15 15 litellm-usage
# Upload a compressed export. Files over 30 MB must be gzipped or zipped first (one CSV per archive).
dci ingest-datahub-events-csv provider: litellm-usage, file: @events.csv.gz
# Script-friendly result, scoped to another customer's tenant.
dci ingest-datahub-events-csv provider: litellm-usage, file: @events.csv --output json -D acme.com
{"batch": "csv_events.csv_1756987200000", "ingestedRows": 15, "generatedEvents": 15, "sourceRecords": 15, "provider": "litellm-usage", "schemaTemplate": "default@1"}

Request

Content-Type: multipart/form-data

FieldTypeRequiredDescription
providerstringThe identifier of the data provider. Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), space, dash (-).
filestring (binary)The CSV file to upload, either uncompressed or compressed in ZIP or GZ format. The maximum file size is 30 MB.
schemaTemplatestringVersioned schema template of the file. Defaults to the dataset's template (default@1 for datasets created without one). Provider-native templates such as anthropic-spend-report@1 and codex-usage-report@1 validate the vendor's own columns and normalize them into DataHub events. Must match the template stored on the dataset.
periodStartstring (date)Inclusive first day of the report period (YYYY-MM-DD). Required for template uploads whose filename does not carry the period; when both are present they must agree.
periodEndstring (date)Inclusive last day of the report period (YYYY-MM-DD). Events are booked on this day.
replacebooleanTemplate uploads only. When true, active batches whose report period overlaps this upload are soft-deleted before the new file is ingested, and their ids are returned in replacedBatches. Refused with 409 when an overlapping batch extends outside the requested period (so a one-day replacement can never remove a wider upload) or was ingested less than 90 minutes ago (Retry-After header set). Without replace, any overlap is rejected with 409. Default: false.
Raw JSON schema
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"description": "The identifier of the data provider. Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), space, dash (-).",
"example": "Datadog"
},
"file": {
"type": "string",
"format": "binary",
"description": "The CSV file to upload, either uncompressed or compressed in ZIP or GZ format. The maximum file size is 30 MB."
},
"schemaTemplate": {
"type": "string",
"description": "Versioned schema template of the file. Defaults to the dataset's template (`default@1` for datasets created without one). Provider-native templates such as `anthropic-spend-report@1` and `codex-usage-report@1` validate the vendor's own columns and normalize them into DataHub events. Must match the template stored on the dataset.",
"example": "anthropic-spend-report@1"
},
"periodStart": {
"type": "string",
"format": "date",
"description": "Inclusive first day of the report period (YYYY-MM-DD). Required for template uploads whose filename does not carry the period; when both are present they must agree.",
"example": "2026-09-10"
},
"periodEnd": {
"type": "string",
"format": "date",
"description": "Inclusive last day of the report period (YYYY-MM-DD). Events are booked on this day.",
"example": "2026-09-10"
},
"replace": {
"type": "boolean",
"default": false,
"description": "Template uploads only. When `true`, active batches whose report period overlaps this upload are soft-deleted before the new file is ingested, and their ids are returned in `replacedBatches`. Refused with `409` when an overlapping batch extends outside the requested period (so a one-day replacement can never remove a wider upload) or was ingested less than 90 minutes ago (`Retry-After` header set). Without `replace`, any overlap is rejected with `409`."
}
}
}

Output

OK - Ingestion succeeded.

By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.

FieldTypeDescription
batchstringbatch id, generated during ingestion
ingestedRowsintegerthe number of events that have been accepted for processing
schemaTemplatestringthe schema template the file was validated against
sourceRecordsintegerthe number of source rows in the file
generatedEventsintegerthe number of DataHub events generated from the source rows
replacedBatchesarray of stringids of the batches soft-deleted because replace was set; omitted when none
Raw JSON schema
{
"type": "object",
"properties": {
"batch": {
"type": "string",
"description": "batch id, generated during ingestion",
"example": "your_file.csv.gz_1730972725212"
},
"ingestedRows": {
"type": "integer",
"description": "the number of events that have been accepted for processing",
"example": 15
},
"schemaTemplate": {
"type": "string",
"description": "the schema template the file was validated against",
"example": "anthropic-spend-report@1"
},
"sourceRecords": {
"type": "integer",
"description": "the number of source rows in the file",
"example": 5
},
"generatedEvents": {
"type": "integer",
"description": "the number of DataHub events generated from the source rows",
"example": 15
},
"replacedBatches": {
"type": "array",
"description": "ids of the batches soft-deleted because `replace` was set; omitted when none",
"items": {
"type": "string"
},
"example": [
"csv_spend-report-…-2026-09-10-to-2026-09-10.csv_1757894400000"
]
}
}
}

Errors

On failure, dci prints a single error message — with a hint when one is available — and exits with a typed code your scripts can branch on. See Errors and exit codes for the full contract.

HTTP status to exit code mapping
HTTP statusExit codeError codeMeaning
40030VALIDATION_ERRORThe arguments or request body were rejected. Review the command's flags and payload.
40110AUTHENTICATION_FAILEDNot signed in, or the API token is invalid. Run dci login or check DCI_API_KEY.
40311PERMISSION_DENIEDThe DoiT user or the active customer context does not have access.
40420RESOURCE_NOT_FOUNDThe requested resource does not exist. Check the identifier argument.
40921RESOURCE_CONFLICTThe operation conflicts with the resource's current state.
50040API_SERVER_ERRORThe API failed to process the request. Retryable; contact DoiT support if it persists.

Aliases: datahub-events-csv-file, datahub-events-csvfile