---
title: "Create the table and start loading its rows"
method: POST
path: "/table-imports/{import_id}/commit/"
tags: ["table-imports"]
---

# Create the table and start loading its rows

`POST /table-imports/{import_id}/commit/`

## Request

- Base URL: `https://api.getoneprofile.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getoneprofile.ai/table-imports/{import_id}/commit/`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Create the table and its columns from the reviewed mapping, then start the row load in the background.

The table exists as soon as this returns, so the client can navigate to it immediately and watch rows arrive. Poll the job to follow progress.

Committing twice is refused: the second call finds the import already running rather than creating a second table.

## Path parameters

- `import_id` string, uuid, required

## Request body

- TableImportCommitRequestSchema: Request body for committing an upload. Send the mapping the user reviewed. Omitting a field's entry leaves that column out of the table entirely, which is how a user drops a column they do not want.
  - `columns` ImportColumnMappingSchema[], required: The reviewed mapping, in display order.
    - `column_type` 'text' | 'paragraph' | 'url' | 'email' | 'image_url' | 'person' | 'select' | 'number' | 'decimal' | 'currency' | 'checkbox' | 'date' | 'multi_select' | 'list' | 'object', required: The type a user picks for a table column. Ordered as the picker shows them, which is also the order the groups below run in: text-ish, then numeric, then choice, then structured.
    - `name` string, required: The column's display name.
    - `source_index` integer, required: The field's zero-based position in the file.
  - `folder_id` string, uuid, nullable: The folder to make the table in, as when the file is imported from inside one on the Tables list. Leave it out for the top level.
  - `max_rows` integer, nullable: How many of the file's data rows to write, counted from the top: 1 or more. Clamped by the plan's own ceiling, so this can only ever import less than the preview's `importable_row_count`, never more. Omit it, or send null, for every row the plan allows; that is also how a file with a header and no data rows is committed. Named for the user's choice, unlike the preview's `row_limit`, which is the plan's cap.
  - `row_ranges` ImportRowRangeSchema[], nullable: Which of the file's data rows to write, the way a print dialog picks pages: rows 1 to 10 and 21 to 30 are two ranges. Rows are numbered as `row_errors` numbers them, from 1 under the header, blank lines not counted. Overlapping and touching ranges are merged, an end past the file's last row is brought back to it, and a choice bigger than the plan's `row_limit` keeps its first rows up to it. Rows past the preview's `importable_row_count` may be chosen: the plan caps how many rows a table holds, not which. A choice wholly past the end of the file is refused, and so is one of more than 100 ranges once merged. Send this or `max_rows`, never both; omit both for every row the plan allows.
    - `first` integer, required: The first row of the range, counted from 1.
    - `last` integer, required: The last row of the range; `first` for one row.
  - `table_name` string, required: Name for the table this creates.

## Response `200`

Successful Response

- TableImportJobResponseSchema: A CSV import's current state. Poll this until `status` is terminal. `imported_rows` climbs as the load runs, so it doubles as a progress bar against `total_rows`.
  - `columns` ImportColumnMappingSchema[], required: The mapping in force.
    - `column_type` 'text' | 'paragraph' | 'url' | 'email' | 'image_url' | 'person' | 'select' | 'number' | 'decimal' | 'currency' | 'checkbox' | 'date' | 'multi_select' | 'list' | 'object', required: The type a user picks for a table column. Ordered as the picker shows them, which is also the order the groups below run in: text-ish, then numeric, then choice, then structured.
    - `name` string, required: The column's display name.
    - `source_index` integer, required: The field's zero-based position in the file.
  - `created_at` string, date-time, required
  - `error` string, nullable, required: Why the whole job failed, if it did.
  - `failed_rows` integer, required: Rows that could not be written: the exact count.
  - `id` string, uuid, required
  - `imported_rows` integer, required: Rows written so far.
  - `row_errors` ImportRowErrorSchema[], required: A capped sample of per-row failures; failed_rows carries the full count.
    - `reason` string, required: Which column rejected the value, and why.
    - `row_number` integer, required: One-based data-row number in the file.
  - `source_filename` string, required
  - `status` 'pending' | 'running' | 'succeeded' | 'failed', required: Where a CSV import has got to. ``PENDING`` is a parsed-and-stored upload the user has not committed yet: it holds an inferred mapping and nothing else. ``RUNNING`` means the table and its columns exist and the row job is inserting. The two terminal states are absorbing: a job never leaves them.
  - `table_id` string, uuid, nullable, required: The table this created; null before commit.
  - `total_rows` integer, required: Rows this import will write: the file's rows, capped by the plan and by whatever `max_rows` the commit asked for, or the rows its `row_ranges` hold.
  - `updated_at` string, date-time, required

## Other responses

- `401`: Unauthorized
- `402`: Plan table limit reached. Upgrade to create more tables.
- `403`: Forbidden
- `404`: Import or folder not found
- `422`: Invalid request made to the API.
- `500`: Internal server error.
- `502`: Bad gateway error.
- `503`: Service unavailable.

---

[API](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile.md) · [All operations](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/llms.txt) · [OpenAPI document](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/revisions/4a6bd71e3f02?raw)
