---
title: "Add a column to a vault"
method: POST
path: "/vaults/{id}/columns"
tags: ["Contract Intelligence"]
---

# Add a column to a vault

`POST /vaults/{id}/columns`

## Request

- Base URL: `https://app.gc.ai/api/external/v1`
- URL: `https://app.gc.ai/api/external/v1/vaults/{id}/columns`
- Auth: API key in header `Authorization`
- TypeScript: <https://skmtc.dev/gc-ai/apis/gc-ai-external-api/docs/vaults/:id/columns/post.ts> (a function with typed inputs; its response is checked against the schema)

Add a column to a vault's table.

Adding a column scans nothing. Documents already in the vault keep an empty cell for the new column until a re-scan fills it, which you start from the vault in the app. Add the columns you want before you upload, and every document that arrives afterwards is read against all of them.

The new column starts hidden in every saved view of this vault. A saved view is a sharing boundary, so a column created after the view was saved never joins it on its own; a member of the view reveals it there when they want it.

`field_key` is frozen at creation. Omit it and GC AI builds one from the label. Renaming the column later leaves the key alone, so the values already extracted stay attached to it.

A vault holds at most 500 columns. Column 501 returns `403` with the message the app shows, and you have to delete a column before adding another.

Requires the `editor` or `owner` role in the vault and the organization-level permission to manage vaults.

Requires a user-scoped API key (`u:gcai_...`). A vault is shared with named people, so an organization-scoped key has no identity to resolve vault access with.

## Path parameters

- `id` string, uuid, required: The vault ID

## Request body

- CreateVaultColumnRequest
  - `label` string, required: The column heading shown in the vault table.
  - `field_key` string: The key extracted values are stored under. Omit it and GC AI builds one from the label (`Renewal notice` becomes `renewalNotice`). Set it when you need the key to match something you already store, because the key is frozen once the column exists: renaming the column later never changes it. Any printable key up to 100 characters works, including one with an underscore or a hyphen; percent-encode it when you address a cell on this column.
  - `instructions` string: Required for an `ai` column: this text is the prompt extraction reads each document with, so say what to look for and what to return. Optional for a `manual` column, where it is only a note to whoever fills the column in.
  - `field_type` 'text' | 'date' | 'date_range' | 'enum' | 'multi_enum' | 'boolean' | 'number' | 'currency' | 'percentage' | 'duration' | 'email' | 'url' | 'list' | 'rich_text': The shape of the values in this column. `enum` and `multi_enum` need `field_meta`; every other type needs `field_meta: null`.
  - `field_meta` union: The option list for an `enum` or `multi_enum` column. Send `null`, or omit it, for every other type.
    - object
      - `type` 'enum', required
      - `options` string[], required: The values this column can hold. Between 2 and 12, all different.
    - object
      - `type` 'multi_enum', required
      - `options` string[], required: The values this column can hold. Between 2 and 12, all different. A document can carry more than one.
    - unknown
  - `extraction_mode` 'ai' | 'manual': How the column gets filled. `ai` (the default) has extraction read it out of each document. `manual` keeps it out of every scan so the values stay exactly what a person types.
  - `sort_order` integer: Placement weight, 0 by default. The table orders columns by `sort_order` first and creation time second, so columns added without one keep the order you added them in.

## Response `201`

The created column

- VaultColumnResponse
  - `id` string, uuid, nullable, required: Unique column identifier, or null for a built-in column. A built-in column has no row of its own in this vault, so it has no ID and cannot be changed or deleted.
  - `field_key` string, required: The stable key extracted values are stored under. It is set once, when the column is created, and never changes, so renaming the column keeps every value already extracted for it.
  - `label` string, required: The column heading shown in the vault table
  - `instructions` string, required: For an `ai` column, the prompt extraction reads each document with. For a `manual`, `import`, or `connector` column, a note to whoever reads the column.
  - `field_type` 'text' | 'date' | 'date_range' | 'enum' | 'multi_enum' | 'boolean' | 'number' | 'currency' | 'percentage' | 'duration' | 'email' | 'url' | 'list' | 'rich_text' | 'party_list' | 'related_agreement_list', required: The shape of the values in this column. Built-in columns can report `party_list` and `related_agreement_list`, which you cannot set yourself.
  - `field_meta` union, required: The option list for an `enum` or `multi_enum` column. Null for every other type.
    - object
      - `type` 'enum', required
      - `options` string[], required: The values extraction can assign to this column.
      - `legacy_options` string[]: Values that documents extracted under an older version of this option list still hold. They stay readable and filterable, and extraction never assigns them again.
    - object
      - `type` 'multi_enum', required
      - `options` string[], required: The values extraction can assign to this column.
    - unknown
  - `extraction_mode` 'ai' | 'manual' | 'import' | 'connector', required: How the column gets filled. `ai`: extraction reads it out of each document. `manual`: a person types it and no scan ever touches it. `import`: values come from a connected spreadsheet, which owns the column. `connector`: values come from a connected document source, which owns the column. You can create `ai` and `manual` columns. An `import` column is created by connecting a spreadsheet in the app. A `connector` column is created when a source such as Ironclad fills it.
  - `kind` 'built_in' | 'system' | 'custom', required: What this column is. `built_in`: merged into every vault by GC AI, with no ID and no way to change it. `system`: owned by this vault but managed by GC AI (Document Name, Document Status, Document Title), so it has an ID but rejects every change and every delete. `custom`: yours, and the only kind `PATCH` and `DELETE` accept.
  - `editable` boolean, required: True when this column can be changed with `PATCH /vaults/{id}/columns/{columnId}`. Built-in and system columns report `false`: GC AI owns their name, type, options, and prompt. One exception, on both surfaces: `sort_order` is list position rather than identity, so it can be set on any column that has an ID.
  - `sort_order` number, nullable, required: Placement weight for this column, or null for a built-in one. The table orders columns by `sort_order` first and creation time second.
  - `created_at` string, nullable, required: ISO 8601 creation timestamp, or null for a built-in column
  - `updated_at` string, nullable, required: ISO 8601 last-update timestamp, or null for a built-in column

## Other responses

- `400`: Invalid request body, a `field_key` that is reserved, underivable, or holds a control character, an option list that is not 2 to 12 unique values, or an `ai` column with no instructions
- `401`: Missing or malformed API key
- `403`: Contract Intelligence is not enabled for this account. Contact support to request access., the caller cannot manage this vault's columns, or the vault has reached its 500 column limit
- `404`: Vault not found or access denied
- `409`: The vault is archived, or a column with that `field_key` already exists
- `422`: Vault access is per-user and requires a user-scoped API key (u:gcai_...).
- `429`: Rate limit exceeded. See [Rate Limits](https://docs.gc.ai/api-reference/concepts/rate-limits) for the tiers, limits, and how to back off.
- `500`: Internal server error
- `503`: Service temporarily unavailable

---

[API](https://skmtc.dev/gc-ai/apis/gc-ai-external-api.md) - [All operations](https://skmtc.dev/gc-ai/apis/gc-ai-external-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gc-ai/apis/gc-ai-external-api/revisions/2bbdfddf7107?raw)
