> ## 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.

# Create or update a workspace attribute

> Creates the attribute, or updates the label, description, options and
position of an attribute that exists.

The type of an attribute that exists cannot change. To store a
different type, archive this attribute and create another one.




## OpenAPI

````yaml /openapi.yaml post /attributes
openapi: 3.1.0
info:
  title: Kai Contacts API
  version: 1.0.0
  description: |
    Push, update, assign and export the contacts of one Kai workspace.

    Every request needs an API key. Make a key in Kai, under
    **Settings → API**. Send the key in the `Authorization` header.

    The API works on one workspace. The key decides which workspace, so no
    request carries a workspace id.
  contact:
    name: Kai support
    url: https://kaisupport.com
servers:
  - url: https://kaisupport.com/api/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Contacts
    description: Customer profiles, their attributes and their account owners.
  - name: Attributes
    description: The attributes that the workspace keeps on every contact.
  - name: Members
    description: The teammates of the workspace. Read-only.
paths:
  /attributes:
    post:
      tags:
        - Attributes
      summary: Create or update a workspace attribute
      description: |
        Creates the attribute, or updates the label, description, options and
        position of an attribute that exists.

        The type of an attribute that exists cannot change. To store a
        different type, archive this attribute and create another one.
      operationId: upsertAttribute
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttributeWrite'
            example:
              key: package
              label: Package
              type: select
              options:
                - Tam Destek
                - Tam Paket
      responses:
        '200':
          description: The attribute was updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttributeEnvelope'
        '201':
          description: The attribute was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttributeEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: An attribute with this key stores a different type.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    AttributeWrite:
      type: object
      required:
        - key
        - label
        - type
      properties:
        key:
          type: string
        label:
          type: string
        description:
          type:
            - string
            - 'null'
        type:
          type: string
          enum:
            - text
            - number
            - boolean
            - date
            - select
            - url
            - email
            - phone
        options:
          type: array
          items:
            type: string
        position:
          type: integer
    AttributeEnvelope:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Attribute'
    Error:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
    Attribute:
      type: object
      properties:
        key:
          type: string
          description: >-
            The API name. It starts with a letter and holds lowercase letters,
            digits and underscores.
        label:
          type: string
        description:
          type:
            - string
            - 'null'
        type:
          type: string
          enum:
            - text
            - number
            - boolean
            - date
            - select
            - url
            - email
            - phone
        options:
          type: array
          items:
            type: string
          description: >-
            The allowed values of a `select` attribute. Empty for the other
            types.
        position:
          type: integer
        archived:
          type: boolean
    ErrorBody:
      type: object
      properties:
        type:
          type: string
          description: A stable machine name for the error.
        message:
          type: string
          description: One sentence for a human reader.
        details:
          description: The attributes or the identities that caused the error.
  responses:
    BadRequest:
      description: Kai could not read the request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: invalid_request
              message: >-
                Send at least one of "external_id", "email", "phone" or
                "identities" so the contact can be matched.
    Unauthorized:
      description: The API key is missing or not valid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: unauthorized
              message: That API key is not valid.
    Forbidden:
      description: The API key does not have the permission that this endpoint needs.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: forbidden
              message: This key does not have the "contacts:write" permission.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        Send your API key as `Authorization: Bearer kai_live_...`.

        Make and revoke keys in Kai, under **Settings → API**. Kai stores only
        a hash of the key, so the full key is shown one time.

````