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

# Créer un attribut d'entreprise

> Creates a custom attribute on your team's companies. The key is derived from the label. The call is idempotent: if an attribute with the same key and type already exists, it returns `201` with that attribute and `already_existed` set to `true`. `options` is required for `DROPDOWN` attributes and rejected for other types.

<Note>
  **Scope requis :** `CRM_WRITE`
</Note>

## Champs du body

| Champ | Type | Requis | Description |
| - | - | - | - |
| `label` | string | oui | Nom affiché, de 1 à 255 caractères, avec au moins une lettre ou un chiffre |
| `type` | string | oui | `TEXT`, `NUMBER`, `DATE`, `BOOLEAN` ou `DROPDOWN` |
| `options` | array | `DROPDOWN` uniquement | Au moins un objet `{ label, key? }`. Refusé pour les autres types |
| `prompt` | string | non | Consigne que l'AI CRM Manager suit pour remplir cet attribut à partir des appels |
| `should_prompt_override` | boolean | non | Indique si l'IA peut écraser une valeur déjà renseignée |

## Dérivation de la clé

La `key` est dérivée du label : minuscules, accents supprimés, séquences de caractères non alphanumériques remplacées par `_`, tronquée à 64 caractères. `Industry segment` devient `industry_segment`. Les clés d'options sont dérivées de la même façon.

Un label qui correspond à une clé réservée est refusé avec `ATTRIBUTE_KEY_RESERVED`. Les clés réservées sont : `id`, `name`, `phone_numbers`, `website`, `industry`, `logo_url`, `last_activity`, `activity_history`, `sms_content`, `created_at` et `updated_at`.

## Réponse

Renvoie `201` avec l'attribut créé. `source` vaut `allo` et `already_existed` vaut `false`.

```json theme={null}
{
  "data": {
    "key": "industry_segment",
    "label": "Industry segment",
    "type": "DROPDOWN",
    "options": [
      { "key": "smb", "label": "SMB" },
      { "key": "enterprise", "label": "Enterprise" }
    ],
    "is_visible": true,
    "prompt": "Choisis le segment correspondant à la taille de l'entreprise mentionnée pendant l'appel.",
    "should_prompt_override": false,
    "source": "allo",
    "created_at": "2026-10-07T14:21:08",
    "updated_at": "2026-10-07T14:21:08",
    "already_existed": false
  }
}
```

## Créer deux fois le même attribut

L'appel peut être répété sans risque. Si un attribut avec la même clé et le même type existe déjà, l'endpoint renvoie `201` avec cet attribut et `already_existed` à `true`. Rien n'est créé et la définition existante reste inchangée. Si la clé existe avec un autre type, la requête renvoie `409 ATTRIBUTE_KEY_CONFLICT`.

## Limites

Chaque type dispose d'un nombre fixe d'emplacements par équipe. Lorsqu'un type est plein, créer un autre attribut de ce type renvoie `409 ATTRIBUTE_SLOTS_EXHAUSTED`. Supprimez un attribut inutilisé ou choisissez un autre type.

Les attributs personnalisés ne sont disponibles que pour les équipes qui utilisent le nouveau modèle de contacts. Les autres équipes reçoivent `404 TEAM_NOT_FOUND`.

## Erreurs

| Statut | Code | Quand |
| - | - | - |
| `400` | `ATTRIBUTE_LABEL_INVALID` | `label` est vide, dépasse 255 caractères ou ne contient ni lettre ni chiffre |
| `400` | `ATTRIBUTE_KEY_RESERVED` | Le label correspond à une clé réservée |
| `400` | `ATTRIBUTE_OPTION_INVALID` | Un attribut `DROPDOWN` n'a aucune option, ou un label d'option est vide, dépasse 255 caractères ou est en doublon |
| `400` | `ATTRIBUTE_OPTIONS_NOT_SUPPORTED` | `options` envoyé pour un type autre que `DROPDOWN` |
| `400` | `INVALID_REQUEST_BODY` | `type` est absent ou inconnu |
| `403` | `API_KEY_INSUFFICIENT_SCOPE` | La clé n'a pas le scope `CRM_WRITE` |
| `404` | `TEAM_NOT_FOUND` | Le workspace n'utilise pas le nouveau modèle de contacts |
| `409` | `ATTRIBUTE_KEY_CONFLICT` | Un attribut avec cette clé existe déjà avec un autre type |
| `409` | `ATTRIBUTE_SLOTS_EXHAUSTED` | Aucun emplacement libre pour ce type |
| `409` | `ATTRIBUTE_CONCURRENT_MODIFICATION` | Les attributs ont été modifiés en même temps. Relancez la requête |


## OpenAPI

````yaml POST /v2/api/crm/companies/attributes
openapi: 3.0.3
info:
  title: Allo API
  description: >-
    Allo API provides programmatic access to your Allo account, allowing you to
    manage webhooks, retrieve calls and contacts, and send SMS messages.


    All requests to `/v1/api/**` endpoints automatically go through quota
    checking and scope validation.
  version: 1.0.0
  contact:
    name: Allo Support
servers:
  - url: https://api.withallo.com
    description: Production server
security: []
tags:
  - name: Summary Templates
    description: >-
      Manage call summary templates that control how AI-generated call summaries
      are structured for your team.
  - name: Webhooks
    description: >-
      Manage webhook endpoints to receive real-time notifications about events
      in your Allo account. Each endpoint subscribes to one or more event topics
      and is verified with a signing secret.
  - name: Calls
    description: >-
      Retrieve and search call records with filtering and pagination. Filter
      calls by your Allo phone number.
  - name: Contacts
    description: >-
      Search and retrieve contact information with sorting and pagination.
      Includes engagement level tracking.
  - name: SMS
    description: Send SMS messages to phone numbers using your Allo numbers.
  - name: Phone Numbers
    description: Retrieve information about your Allo phone numbers.
  - name: Analytics
    description: Pre-computed call metrics, team performance, and outbound dial funnel
  - name: CRM
    description: Manage people, companies, and deals in your CRM.
  - name: Notes
    description: >-
      Internal team notes on conversations and CRM people, with @mention
      support. Notes are never visible to the contact.
  - name: Threads
    description: >-
      Team discussion threads attached to a conversation item (call, SMS, or
      conversation note). One thread per item.
  - name: AI Receptionist
    description: >-
      Read and write the AI receptionist configuration of a phone line: business
      details, voice, prompt, capabilities, business hours, transfer rules,
      scheduling calendars and knowledge sources.
paths:
  /v2/api/crm/companies/attributes:
    post:
      tags:
        - CRM
      summary: Create custom company attribute
      description: >-
        Creates a custom attribute on your team's companies. The key is derived
        from the label. The call is idempotent: if an attribute with the same
        key and type already exists, it returns `201` with that attribute and
        `already_existed` set to `true`. `options` is required for `DROPDOWN`
        attributes and rejected for other types.
      operationId: createCompanyAttribute
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCompanyAttributeRequest'
            example:
              label: Industry segment
              type: DROPDOWN
              options:
                - label: SMB
                - label: Enterprise
              prompt: >-
                Pick the segment that matches the company size mentioned on the
                call.
      responses:
        '201':
          description: >-
            The attribute that was created, or the existing one when
            `already_existed` is `true`
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    allOf:
                      - $ref: '#/components/schemas/CompanyAttribute'
                      - type: object
                        properties:
                          already_existed:
                            type: boolean
                            description: >-
                              `true` when an attribute with the same key and
                              type already existed and nothing was created
              example:
                data:
                  key: industry_segment
                  label: Industry segment
                  type: DROPDOWN
                  options:
                    - key: smb
                      label: SMB
                    - key: enterprise
                      label: Enterprise
                  is_visible: true
                  prompt: >-
                    Pick the segment that matches the company size mentioned on
                    the call.
                  should_prompt_override: false
                  source: allo
                  created_at: '2026-10-07T14:21:08'
                  updated_at: '2026-10-07T14:21:08'
                  already_existed: false
        '400':
          $ref: '#/components/responses/ApiValidationError'
        '401':
          $ref: '#/components/responses/ApiUnauthorized'
        '403':
          $ref: '#/components/responses/ApiForbidden'
        '404':
          $ref: '#/components/responses/ApiNotFound'
        '409':
          $ref: '#/components/responses/ApiConflict'
        '429':
          $ref: '#/components/responses/ApiRateLimited'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    CreateCompanyAttributeRequest:
      type: object
      required:
        - label
        - type
      properties:
        label:
          type: string
          description: >-
            Display name of the attribute. The attribute key is derived from it:
            lowercase, accents removed, runs of non-alphanumeric characters
            replaced by `_`, truncated to 64 characters. Labels that resolve to
            a reserved key are rejected.
          example: Industry segment
        type:
          type: string
          enum:
            - TEXT
            - NUMBER
            - DATE
            - BOOLEAN
            - DROPDOWN
          example: DROPDOWN
        options:
          type: array
          description: >-
            Allowed values. Required, with at least one option, for `DROPDOWN`;
            rejected for other types.
          items:
            $ref: '#/components/schemas/CompanyAttributeOptionInput'
        prompt:
          type: string
          nullable: true
          description: >-
            Instruction the AI CRM Manager follows to fill this attribute from
            calls. A blank value clears it.
          example: >-
            Pick the segment that matches the company size mentioned on the
            call.
        should_prompt_override:
          type: boolean
          description: Whether the AI may overwrite a value that is already set
    CompanyAttribute:
      type: object
      description: A custom attribute on companies
      properties:
        key:
          type: string
          description: Unique key within your team
          example: industry_segment
        label:
          type: string
          nullable: true
          description: Display name
          example: Industry segment
        type:
          type: string
          nullable: true
          enum:
            - TEXT
            - NUMBER
            - DATE
            - BOOLEAN
            - DROPDOWN
          example: DROPDOWN
        options:
          type: array
          nullable: true
          description: Allowed values. Only set for `DROPDOWN` attributes.
          items:
            $ref: '#/components/schemas/CompanyAttributeOption'
        is_visible:
          type: boolean
          description: Whether the attribute is shown in the Allo apps
        prompt:
          type: string
          nullable: true
          description: >-
            Instruction the AI CRM Manager follows to fill this attribute from
            calls. A blank value clears it.
          example: >-
            Pick the segment that matches the company size mentioned on the
            call.
        should_prompt_override:
          type: boolean
          description: Whether the AI may overwrite a value that is already set
          nullable: true
        source:
          type: string
          description: >-
            `allo` for attributes created in Allo or with the API, otherwise the
            lowercase name of the integration that manages it, such as `hubspot`
          example: allo
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    CompanyAttributeOptionInput:
      type: object
      required:
        - label
      properties:
        label:
          type: string
          description: Display name of the option
          example: Enterprise
        key:
          type: string
          description: >-
            Existing option key. Send it when editing an attribute to keep the
            option's key stable while its label changes. Keys that do not match
            an existing option are ignored and a key is derived from the label.
          example: enterprise
    CompanyAttributeOption:
      type: object
      properties:
        key:
          type: string
          example: enterprise
        label:
          type: string
          example: Enterprise
    ApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
            code:
              type: string
            message:
              type: string
            retryable:
              type: boolean
            request_id:
              type: string
            retry_after_seconds:
              type: integer
              nullable: true
  responses:
    ApiValidationError:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ApiUnauthorized:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ApiForbidden:
      description: API key lacks the required scope or access to the resource
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ApiNotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ApiConflict:
      description: Conflict with existing resource
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ApiRateLimited:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.