---
title: "Add Columns to Contacts Table"
method: POST
path: "/v3/contacts/tables/{table_id}/columns"
tags: ["Contacts Tables"]
---

# Add Columns to Contacts Table

`POST /v3/contacts/tables/{table_id}/columns`

## Request

- Base URL: `https://api.lusha.com`
- URL: `https://api.lusha.com/v3/contacts/tables/{table_id}/columns`
- Auth: API key in header `api_key`
- TypeScript: <https://skmtc.dev/lusha/apis/lusha-api-documentation/docs/v3/contacts/tables/:table_id/columns/post.ts> (a function with typed inputs; its response is checked against the schema)

Add up to 10 Lusha columns to a table in one call. Enrichment starts automatically on
**all rows** in the table as soon as the columns are added.

**Body** — either a list or a single key:
- `columns: [{ "columnKey": "jobTitle" }, { "columnKey": "seniority" }]`
- `columnKey: "jobTitle"` for a single column

Keys come straight from
[Get Contacts Column Catalog](#operation/getContactsColumnCatalog).

**Partial success:** columns are handled independently. The response returns one entry
per requested column with its own `status` (`added` / `failed`) and `columnId` — if one
column fails the rest still go through. The most common failure is the column already
being on the table, in which case the existing `columnId` is returned, so the call is
safe to re-run.

> **Billing:** Free today — credits aren't charged for adding columns yet.

## Path parameters

- `table_id` string, required

## Request body

- union: Supply either `columns` (up to 10 entries) or a single `columnKey` — not both. Sending neither returns `400`.
  - object
    - `columns` ColumnsAddItem[], required: Up to 10 Lusha columns to add in one call.
      - `columnKey` string, required: A `columnKey` from the column catalog endpoint.
    - `columnKey` string: Shorthand for adding exactly one column.
    - `owner` TableOwner: Identifies the user acting on the table, and resolves to a user on your account. Required on every table-route call when authenticating with an API key (there is no signed-in user) — omitting it returns `400`. Optional for OAuth/token callers, since the caller is already identified by the token; still accepted if you want to act on behalf of another owner.
      - `email` string, email: Must resolve to an existing user on the account tied to your API key.
  - object
    - `columns` ColumnsAddItem[]: Up to 10 Lusha columns to add in one call.
      - `columnKey` string, required: A `columnKey` from the column catalog endpoint.
    - `columnKey` string, required: Shorthand for adding exactly one column.
    - `owner` TableOwner: Identifies the user acting on the table, and resolves to a user on your account. Required on every table-route call when authenticating with an API key (there is no signed-in user) — omitting it returns `400`. Optional for OAuth/token callers, since the caller is already identified by the token; still accepted if you want to act on behalf of another owner.
      - `email` string, email: Must resolve to an existing user on the account tied to your API key.

## Response `200`

Columns processed. Returns one entry per requested column — check each entry's `status`, as some may have failed while others succeeded.

- ColumnsAddResponse: One entry per requested column. Enrichment runs asynchronously on every row in the table for each successfully added column — poll Get Table for `isProcessing` and per-column row-status counts, then read the values via Get Table Entities.
  - `data` ColumnsAddResultItem[]
    - `columnKey` string
    - `columnId` string: ID of the column on this table. Present on `added`, and also on a `COLUMN_ALREADY_EXISTS` failure — in that case it's the ID of the column that was already there, so the request can simply be re-run.
    - `status` 'added' | 'failed'
    - `error` ColumnsAddItemError: Present only when `status` is `failed`.
      - `code` 'COLUMN_ALREADY_EXISTS' | 'COLUMN_KEY_NOT_FOUND' | 'COLUMN_LIMIT_EXCEEDED' | 'UNKNOWN_ERROR': `COLUMN_ALREADY_EXISTS` is the most common — the column is already on the table, and the existing `columnId` is returned alongside it.
      - `message` string
  - `billing` V3Billing: Credit usage summary for a V3 API request
    - `creditsCharged` integer: Total credits charged for this request
    - `resultsReturned` integer: Number of successful results returned

## Other responses

- `400`: Bad request - invalid input data
- `401`: Unauthorized - invalid or missing API key
- `403`: Forbidden - account inactive, V3 access not enabled, or plan does not include this feature
- `404`: Not found - table does not exist or is not accessible to this account

## Changes

- **2026-09-11** `061e7f600fb8`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/lusha/apis/lusha-api-documentation/changes/v3/contacts/tables/:table_id/columns/post.md)

---

[API](https://skmtc.dev/lusha/apis/lusha-api-documentation.md) - [All operations](https://skmtc.dev/lusha/apis/lusha-api-documentation/llms.txt) - [OpenAPI document](https://skmtc.dev/lusha/apis/lusha-api-documentation/revisions/3d811e5b108c?raw)
