> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kaisupport.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspace attributes

> The fields that your workspace keeps on every contact.

A workspace attribute is a field that you define. It appears on every contact
profile, in the inbox, and in the API. You do not need a migration or a
release to add one.

An attribute has two names. The **label** is what a teammate reads, for example
`Package`. The **API name** is the key that a script sends, for example
`package`. The label can change at any time. The API name cannot, so a
renamed label never breaks your sync.

## Types

| Type      | Stored as            | Accepted input                                        |
| --------- | -------------------- | ----------------------------------------------------- |
| `text`    | string               | any string, up to 4096 characters                     |
| `number`  | number               | `42`, `"42"`, `"3,5"`                                 |
| `boolean` | boolean              | `true`, `"yes"`, `"evet"`, `false`, `"no"`, `"hayır"` |
| `date`    | string, `YYYY-MM-DD` | `"2027-06-20"`, or a date that JavaScript can parse   |
| `select`  | string               | one of the options, in any case                       |
| `url`     | string               | an `http` or `https` URL                              |
| `email`   | string               | an email address, stored lowercase                    |
| `phone`   | string               | a phone number                                        |

Kai accepts the JSON type and its string spelling, because a CSV export and a
spreadsheet lose types. Kai does not accept a wrong meaning: an unknown
`select` option is an error, not a stored spelling mistake.

## Create an attribute

```bash theme={null}
curl -X POST https://kaisupport.com/api/v1/attributes \
  -H "Authorization: Bearer $KAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "exam_year",
    "label": "Exam year",
    "type": "number",
    "description": "The year of the exam that this student prepares for."
  }'
```

An API name starts with a letter. It holds lowercase letters, digits and
underscores, up to 48 characters.

## Unknown keys are errors

Kai refuses an attribute key that the workspace does not define, and names the
key:

```json theme={null}
{
  "error": {
    "type": "invalid_attributes",
    "message": "Some attributes could not be stored.",
    "details": [{ "key": "cohort", "message": "no such workspace attribute" }]
  }
}
```

Kai refuses the key instead of dropping it. A push of 3000 contacts that
silently discards the one field you care about is a fault that nobody finds
until months later.

## Types cannot change

The type of an attribute that exists is fixed. To store a different type,
archive the attribute and create another one with a new API name.

A type change would leave every recorded value unreadable by its own
definition, and no conversion is correct for all of them.

## Archive, not delete

`DELETE /attributes/{key}` archives the attribute:

* the attribute stops being offered in Kai;
* Kai refuses new writes to it;
* every value that contacts already hold stays, and the profile still shows it.

Send `?restore=true` to make the attribute writable again.
