Bulk import

Upload Parquet files for bulk import into existing tables and list the status of bulk import jobs.

Bulk import endpoints require the upgraded storage engine, enabled with the --use-pacha-tree flag, and a compactor node that runs the bulk import scheduler to complete the import. All endpoints require an admin (operator) token.

GET /api/v3/enterprise/import

List bulk import statuses

Lists the status of bulk import jobs, for both uploads and object-store pulls.

Requires a token with the describe action on at least one database, or an admin token. The list includes only jobs for databases the token can describe. A token that can’t describe any database gets 403.

Requires the upgraded storage engine (enabled with the --use-pacha-tree flag).

This endpoint is only available in InfluxDB 3 Enterprise.

Example request Ask AI about this
curl --request GET \
  "https://localhost:8181/api/v3/enterprise/import" \
  --header "Authorization: Bearer INFLUX_TOKEN"

Responses

200 Success. Returns the list of bulk import statuses.
401 Unauthorized access.
data object
error string
403 Access denied.
data object
error string
500 Internal server error. Object store or read failure.
data object
error string
POST /api/v3/enterprise/import

Import Parquet data

Imports Parquet data into an existing table. Send the data one of two ways:

  • Upload (multipart/form-data): send one Parquet file in the request.
  • Object-store pull (application/json): name a source prefix, and the server imports every Parquet file under it. The source is either a prefix in the cluster’s own object store or an s3://bucket/prefix URL. The server reads another bucket with its own object-store credentials; the request carries none, so those credentials must be able to read the bucket. A server whose own object store isn’t S3 can’t read another bucket and returns 400.

The request returns after the import is staged. The compactor node imports the data asynchronously. A job moves through queued, imported, and compacted; rows become queryable once the job is compacted. Use List bulk import statuses to follow it.

Column types

For generic Parquet files, a column that isn’t in column_metadata is imported as a field, typed from its Parquet type. This applies even when the target table already declares the column as a tag, so map every string tag column (for example, {"column_mapping": {"host": "tag"}}). Otherwise the import fails with invalid column type for column 'host', expected iox::column_type::tag, got iox::column_type::field::string. A string column with no mapping can also fail with 400 Unable to infer data type for column.

Explicit schema databases

In a database created with schema_mode: explicit, every column in the file must already be declared on the table. Otherwise the import is rejected and no job is created. Declare columns with PATCH /api/v3/configure/table.

Permissions

Requires a token with the write action on the target database (for example, db:DATABASE_NAME:write), or an admin token. For a token without that permission, including when the database doesn’t exist, the request returns 403.

Requires the upgraded storage engine (enabled with the --use-pacha-tree flag); the compactor node runs the bulk import scheduler that completes the import.

This endpoint is only available in InfluxDB 3 Enterprise.

Request body required

Content-Type: application/json
column_metadata object
Column metadata for a bulk import. Maps column names to InfluxDB column types to declare tag, field, and time columns.
Example: {"column_mapping":{"room":"tag","temp":"f64","time":"time"}}
column_mapping required object
A map of column name to InfluxDB column type. The JSON key accepts the aliases column_mapping, schema, and column_metadata.
database required string
The target database name. The database must already exist.
source required string
Where to read Parquet files: a prefix in the cluster’s own object store (for example, staging/exports/), or an s3://bucket/prefix URL. Every Parquet file under the prefix is imported.
table required string
The target table name. The table must already exist.
Example request Ask AI about this
curl --request POST \
  "https://localhost:8181/api/v3/enterprise/import" \
  --header "Authorization: Bearer INFLUX_TOKEN" \
  --header "Content-Type: application/json" \
  --data-raw '{
  "column_metadata": {
    "column_mapping": {
      "room": "tag",
      "temp": "f64",
      "time": "time"
    }
  },
  "database": "DATABASE",
  "source": "SOURCE",
  "table": "TABLE"
}'

Responses

200 Success. The upload has been staged for import.
column_metadata object
Column metadata for a bulk import. Maps column names to InfluxDB column types to declare tag, field, and time columns.
Example: {"column_mapping":{"room":"tag","temp":"f64","time":"time"}}
column_mapping required object
A map of column name to InfluxDB column type. The JSON key accepts the aliases column_mapping, schema, and column_metadata.
completed_at integer <int64>
When the import completed, in nanoseconds since the Unix epoch.
created_at required integer <int64>
When the uploaded file was ready for import, in nanoseconds since the Unix epoch.
db_id required integer
The ID of the database resolved from the supplied name.
filename required string
The filename of the uploaded Parquet data file.
iox_parquet required boolean
Whether the file was written by IOx (richer embedded metadata).
last_message string
The last error message if the job has errored.
last_updated_at integer <int64>
When this info last changed, in nanoseconds since the Unix epoch.
max_timestamp_ns required integer <int64>
The maximum timestamp in the file (nanoseconds), from the time column’s Parquet statistics. 0 when the file has no statistics the server can read; the imported data isn’t affected.
min_timestamp_ns required integer <int64>
The minimum timestamp in the file (nanoseconds), from the time column’s Parquet statistics. 0 when the file has no statistics the server can read; the imported data isn’t affected.
row_count required integer <int64>
The row count from Parquet metadata.
size_bytes required integer <int64>
The total size of the uploaded Parquet file in bytes.
started_at integer <int64>
When the import began, in nanoseconds since the Unix epoch.
status required string
The status of a bulk import job. A successful job moves through queued, imported, and compacted; its rows become queryable once it’s compacted, not when it’s imported.
Allowed: queued , dispatched , imported , compacted , failed , terminal_failed
table_id required integer
The ID of the table resolved from the supplied name.
upload_uuid required string
The UUID of the upload.
400 Bad request. Possible reasons: missing multipart boundary; missing file_bytes, database, or table; unparseable multipart; invalid or empty Parquet; malformed column_metadata; column type or mapping mismatch; or a missing time column.
data object
error string
401 Unauthorized access.
data object
error string
403 Forbidden. The token doesn’t have the write action on the target database. A token without that permission also gets 403 when the database doesn’t exist (Not authorized to import into database).
data object
error string
404 Not found. The target table does not exist (“Table cpu does not exist”).
data object
error string
500 Internal server error. Object store, status write, or catalog failure. In 3.12, a file whose columns don’t match the table also returns 500 with Could not modify catalog: a column that an explicit schema database doesn’t declare, or an unmapped string column that the table declares as a tag.
data object
error string

Was this page helpful?

Thank you for your feedback!