import-datahub-provider-records
dci import-datahub-provider-records [body]
Sends provider-native records as JSON instead of a CSV file. The records use the same columns as the template's CSV (currently anthropic-spend-report@1 only) and are validated, normalized and booked on periodEnd exactly like a CSV upload. 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.
provider, schemaTemplate, periodStart, periodEnd and records are required. provider is
the name of an existing dataset (dci list-datahub-datasets). Today the only supported
schemaTemplate is anthropic-spend-report@1; each record uses that template's CSV column
names, and decimals may be strings or numbers. Records are validated, normalized and booked on
periodEnd exactly like a CSV upload, and replace has the same meaning as for
dci ingest-datahub-events-csv. Data can take up to 15 minutes to appear in the DoiT console.
A 409 means the period overlaps an active batch (upload without replace), the template does
not match the dataset, replace would remove data outside the period, or an overlapping batch is
still processing.
Examples
# Import one day of provider-native records from a JSON file (the usual way, since `records` is an array of objects).
dci import-datahub-provider-records < records.json
# records.json
{"provider": "Anthropic Team",
"schemaTemplate": "anthropic-spend-report@1",
"periodStart": "2026-09-10",
"periodEnd": "2026-09-10",
"records": [
{"user_email": "[email protected]", "account_uuid": "<account-uuid>",
"product": "Claude Code", "model": "claude-sonnet-4-6",
"total_requests": 1, "total_prompt_tokens": 100, "total_completion_tokens": 20,
"total_net_spend_usd": "1.20", "total_gross_spend_usd": "1.50",
"total_uncached_input_tokens": 60, "total_cache_read_tokens": 20,
"total_cache_write_5m_tokens": 10, "total_cache_write_1h_tokens": 10,
"total_web_search_count": 0}]}
# Re-import a period, replacing the batch already loaded for it.
dci import-datahub-provider-records replace: true < records.json
# Check the result in a script.
dci import-datahub-provider-records < records.json --output json | jq '{batch, ingestedRows, generatedEvents}'
The response reports `batch`, `ingestedRows`, `sourceRecords`, `generatedEvents` and any `replacedBatches`.
Request
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | Existing dataset (provider) name. |
schemaTemplate | string | yes | Versioned schema template of the records. |
periodStart | string (date) | yes | |
periodEnd | string (date) | yes | |
replace | boolean | Same semantics as the replace field of the CSV upload. Default: false. | |
records | array of object | yes | One object per source row; keys are the template's CSV column names. Decimals may be strings or numbers. |
Raw JSON schema
{
"type": "object",
"required": [
"provider",
"schemaTemplate",
"periodStart",
"periodEnd",
"records"
],
"properties": {
"provider": {
"type": "string",
"description": "Existing dataset (provider) name.",
"example": "Anthropic Team"
},
"schemaTemplate": {
"type": "string",
"description": "Versioned schema template of the records.",
"example": "anthropic-spend-report@1"
},
"periodStart": {
"type": "string",
"format": "date",
"example": "2026-09-10"
},
"periodEnd": {
"type": "string",
"format": "date",
"example": "2026-09-10"
},
"replace": {
"type": "boolean",
"default": false,
"description": "Same semantics as the `replace` field of the CSV upload."
},
"records": {
"type": "array",
"description": "One object per source row; keys are the template's CSV column names. Decimals may be strings or numbers.",
"items": {
"type": "object",
"additionalProperties": true
},
"example": [
{
"account_uuid": "00000000-0000-0000-0000-000000000000",
"product": "Claude Code",
"model": "claude-sonnet-4-6",
"total_requests": 1,
"total_prompt_tokens": 100,
"total_completion_tokens": 20,
"total_net_spend_usd": "1.20",
"total_gross_spend_usd": "1.50",
"total_uncached_input_tokens": 60,
"total_cache_read_tokens": 20,
"total_cache_write_5m_tokens": 10,
"total_cache_write_1h_tokens": 10,
"total_web_search_count": 0
}
]
}
}
}
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.
| Field | Type | Description |
|---|---|---|
batch | string | |
ingestedRows | integer | |
schemaTemplate | string | |
sourceRecords | integer | |
generatedEvents | integer | |
replacedBatches | array of string |
Raw JSON schema
{
"type": "object",
"properties": {
"batch": {
"type": "string",
"example": "api_1757894400000"
},
"ingestedRows": {
"type": "integer",
"example": 15
},
"schemaTemplate": {
"type": "string",
"example": "anthropic-spend-report@1"
},
"sourceRecords": {
"type": "integer",
"example": 5
},
"generatedEvents": {
"type": "integer",
"example": 15
},
"replacedBatches": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
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 status | Exit code | Error code | Meaning |
|---|---|---|---|
| 400 | 30 | VALIDATION_ERROR | The arguments or request body were rejected. Review the command's flags and payload. |
| 401 | 10 | AUTHENTICATION_FAILED | Not signed in, or the API token is invalid. Run dci login or check DCI_API_KEY. |
| 403 | 11 | PERMISSION_DENIED | The DoiT user or the active customer context does not have access. |
| 404 | 20 | RESOURCE_NOT_FOUND | The requested resource does not exist. Check the identifier argument. |
| 409 | 21 | RESOURCE_CONFLICT | The operation conflicts with the resource's current state. |
| 500 | 40 | API_SERVER_ERROR | The API failed to process the request. Retryable; contact DoiT support if it persists. |
Related
- ingest-datahub-events-csv — Ingest CSV file
- ingest-datahub-events — Ingest JSON
- create-datahub-dataset — Create dataset
- list-datahub-datasets — List datasets
- delete-datahub-events-by-filter — Delete specific events
- API reference: POST /datahub/v1/import
Aliases: datahub-import-provider-records