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

# Edit the card

> Moves the card to another stage or board, changes the owner, marks it as won or lost, and updates status, due date and description. Send only the fields you want to change. The others stay as they are.

The change follows the same rules as the panel: the position within the stage is recalculated when the card changes stage, the origin can be given by name, the card's history records the change with source `api`, and automations receive the movement events.

**Winning the card** (`won: true`) moves the card to the stage marked as done on the board, fills in `wonDate` and clears the status. If the board has no done stage, the response is `400 ERR_CRM_BOARD_WITHOUT_DONE_LIST`. `won: null` undoes the win and clears the date.

Products are not changed here. Use `PUT /crm/cards/{cardId}/products`, which requires a product already registered in the catalog.

The card's position is not sent here either. It is recalculated automatically when the card changes stage.



## OpenAPI

````yaml /api-reference/openapi.en.yaml put /crm/cards/{cardId}
openapi: 3.0.3
info:
  title: Connecta DESK Public API
  version: 1.0.0
  description: >-
    Public API of Connecta DESK, available at `/api/v1`. Access uses a token
    generated in the tokens module. Each token has permissions per **module ×
    method**, and every list read is paginated.


    ## Authentication


    ```

    Authorization: Bearer sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

    ```


    The token belongs to a **company**, not to a user. The company used is
    always the token's company, so sending `companyId` in the body has no
    effect. A missing, invalid, revoked or expired token gets the same `401`
    response.


    ## Order of checks


    1. **token** → `401`

    2. **active company** → `403`

    3. **API enabled on the plan** → `403 ERR_API_NOT_ENABLED` (does not apply
    to on-premise)

    4. **company rate limit** → `429`

    5. **token permission** → `403 ERR_API_FORBIDDEN_SCOPE`


    ## User ids


    Every user id in the API is the user's id **in this company**, the same one
    `GET /users` returns. This applies to what the API returns (`user.id`,
    `assignedTo.id`, `userCreated.id`) and to what it accepts (`userId`,
    `userIds`, `assignedToUserId` and the `{id}` in user routes).


    The same person can work in several companies, with a different name and
    profile in each one, and has a different id in each company.


    An id that does not belong to this company returns `404`, with the same
    message as an id that does not exist.


    ## Pagination


    Every list `GET` is paginated. The `meta` contains only `page`, `perPage`
    and `hasMore`, without the total number of records. To go through
    everything, keep advancing `page` while `hasMore` is `true`.


    ## Idempotency


    Optional on `POST`/`PUT`, through the `Idempotency-Key` header. If you
    repeat the call with the same key and the same body, you get the stored
    response (with `Idempotent-Replay: true`). With the same key and a different
    body, the response is `409`.
servers:
  - url: https://api.connectadesk.com/api/v1
    description: Production
security:
  - apiToken: []
tags:
  - name: contacts
    description: Contact records, extra fields and marketing source.
  - name: tickets
    x-displayName: Tickets
    description: Opening, transferring, closing and wrap-up of tickets.
  - name: messages
    description: Asynchronous sending and reading of messages.
  - name: tags
    description: Tags and their link to tickets.
  - name: queues
    description: Service queues and their agents.
  - name: wrapups
    description: Wrap-up types.
  - name: users
    description: Agents and administrators.
  - name: schedules
    description: Scheduled messages.
  - name: quick-messages
    description: Quick replies.
  - name: campaigns
    description: Bulk sending.
  - name: crm
    description: Boards, stages, cards and metrics.
  - name: channels
    description: Channels (read only).
  - name: reports
    description: Reports and dashboards.
  - name: products
    description: Product catalog, categories and sales performance.
  - name: custom-fields
    description: Custom fields for contacts and cards, plus company-wide global variables.
  - name: profiles
    description: Company permission profiles (read only).
  - name: webchat
    description: >-
      Native webchat from your own system: open a visitor session, send and read
      messages. The token needs the `webchat` scope (GET and POST).
paths:
  /crm/cards/{cardId}:
    parameters:
      - name: cardId
        in: path
        required: true
        schema:
          type: integer
    put:
      tags:
        - crm
      summary: Edit the card
      description: >-
        Moves the card to another stage or board, changes the owner, marks it as
        won or lost, and updates status, due date and description. Send only the
        fields you want to change. The others stay as they are.


        The change follows the same rules as the panel: the position within the
        stage is recalculated when the card changes stage, the origin can be
        given by name, the card's history records the change with source `api`,
        and automations receive the movement events.


        **Winning the card** (`won: true`) moves the card to the stage marked as
        done on the board, fills in `wonDate` and clears the status. If the
        board has no done stage, the response is `400
        ERR_CRM_BOARD_WITHOUT_DONE_LIST`. `won: null` undoes the win and clears
        the date.


        Products are not changed here. Use `PUT /crm/cards/{cardId}/products`,
        which requires a product already registered in the catalog.


        The card's position is not sent here either. It is recalculated
        automatically when the card changes stage.
      requestBody:
        required: true
        content:
          application/json:
            examples:
              moverDeEtapa:
                summary: Move stage
                value:
                  crmBoardListId: 32
                  note: Pagamento confirmado, seguiu para separação.
              reatribuir:
                summary: Reassign
                value:
                  assignedToUserId: 3
              marcarComoGanho:
                summary: Mark as won
                value:
                  won: true
                  statusReason: Fechou o plano anual.
              marcarComoPerdido:
                summary: Mark as lost
                value:
                  won: false
                  statusReason: Comprou do concorrente.
              editarDados:
                summary: Edit data
                value:
                  name: 'Pedido #88213, 2ª via'
                  description: Customer asked for a call back on Monday morning.
                  due: '2026-09-15T12:00:00.000Z'
                  origin: Indicação
            schema:
              type: object
              minProperties: 1
              description: >-
                Send at least one field. A body with no editable field returns
                `400`.
              properties:
                name:
                  type: string
                  description: Card name.
                  example: 'Pedido #88213'
                description:
                  type: string
                  description: Card description.
                due:
                  type: string
                  format: date-time
                  nullable: true
                  description: >-
                    Card due date, in ISO 8601. **Without a time zone, your
                    company's time zone applies**

                    — `2026-09-15T12:00:00` is noon in your operation. With an
                    explicit offset

                    (`-03:00`) or in UTC (`Z`), the value is respected as it is.
                  example: '2026-09-15T12:00:00-03:00'
                crmBoardListId:
                  type: integer
                  description: Moves the card to this stage.
                  example: 31
                crmBoardId:
                  type: integer
                  description: Moves the card to another board.
                  example: 7
                assignedToUserId:
                  type: integer
                  nullable: true
                  description: >-
                    Changes the card's owner. `null` leaves the card with no
                    owner.
                  example: 3
                crmOriginId:
                  type: integer
                  nullable: true
                  description: Card origin, given by id.
                  example: 5
                origin:
                  type: string
                  description: >-
                    Card origin, given by name. If it does not exist yet, it is
                    created.
                  example: Instagram
                crmBusinessId:
                  type: integer
                  nullable: true
                  description: Business linked to the card.
                  example: 9
                crmBoardCardStatusId:
                  type: integer
                  nullable: true
                  description: >-
                    Only cards with this status. Statuses are configured on each
                    stage.
                  example: 2
                won:
                  type: boolean
                  nullable: true
                  description: >-
                    `true` marks the card as won and moves it to the done stage.
                    `false` marks it as lost. `null` puts the card back in
                    progress.
                statusReason:
                  type: string
                  description: Reason for the win or the loss.
                  example: Fechou o plano anual.
                note:
                  type: string
                  description: Note recorded on the card along with this change.
                  example: Cliente pediu para ligar depois das 14h.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CrmCard'
        '400':
          description: >-
            No editable field was sent, or the card was marked as won on a board
            with no done stage.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: ERR_CRM_BOARD_WITHOUT_DONE_LIST
                  message: O painel não tem etapa marcada como concluída.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The card does not exist or belongs to another company.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  schemas:
    CrmCard:
      type: object
      description: >-
        A card on a CRM board. The response includes only the fields listed
        here.
      properties:
        id:
          type: integer
        name:
          type: string
          description: Display name.
        description:
          type: string
          nullable: true
          description: Card description.
        won:
          type: boolean
          description: Card marked as won.
        wonDate:
          type: string
          format: date-time
          nullable: true
        statusReason:
          type: string
          nullable: true
          description: Reason recorded when the card was won or lost.
          example: Fechou o plano anual.
        boardId:
          type: integer
          description: CRM board the card belongs to.
          example: 7
        list:
          type: object
          nullable: true
          description: Stage the card is in.
          properties:
            id:
              type: integer
            name:
              type: string
              description: Display name.
        status:
          type: object
          nullable: true
          properties:
            id:
              type: integer
            name:
              type: string
              description: Display name.
            color:
              type: string
              nullable: true
              description: Color in hexadecimal, with `#`.
              example: '#6941C6'
        business:
          type: object
          nullable: true
          properties:
            id:
              type: integer
            name:
              type: string
              description: Display name.
        origin:
          type: object
          nullable: true
          properties:
            id:
              type: integer
            name:
              type: string
              description: Display name.
        assignedTo:
          type: object
          nullable: true
          description: >-
            Person responsible for the card. The name is the one this person
            uses in this company.
          properties:
            id:
              type: integer
            name:
              type: string
              description: Display name.
        contacts:
          type: array
          description: >-
            Contacts linked to the card, with their full data, including tags,
            custom fields and all marketing fields. You do not need to call `GET
            /contacts/{id}` for each one.
          items:
            $ref: '#/components/schemas/Contact'
        products:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
              productId:
                type: integer
                nullable: true
                example: 55
              name:
                type: string
                description: Display name.
              sku:
                type: string
                nullable: true
                example: CAM-PRETA-M
              quantity:
                type: number
                description: Product quantity.
                example: 2
              unitPrice:
                type: number
                description: Unit price charged.
                example: 149.9
              totalPrice:
                type: number
                description: >-
                  Total amount for the item, calculated by the server as
                  `quantity` × `unitPrice`.
                example: 299.8
        productsTotal:
          type: number
          description: Sum of all the products on the card.
        customFields:
          type: array
          description: >-
            CRM custom fields (`application: card`) filled in on this card.
            Always included in the response, as an empty list when the card has
            none.
          items:
            $ref: '#/components/schemas/CustomFieldValue'
        creationSource:
          type: string
          nullable: true
          enum:
            - api
            - user
            - bot
            - automation
          description: |-
            How the card was created:

            | value | meaning |
            | --- | --- |
            | `api` | This API. |
            | `user` | A person, through the panel. |
            | `bot` | A chatbot. |
            | `automation` | A Flow automation. |
        due:
          type: string
          format: date-time
          nullable: true
          example: '2026-09-15T12:00:00.000Z'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      example:
        id: 4471
        name: 'Pedido #88213'
        description: Customer asked for a call back on Monday morning.
        won: false
        wonDate: null
        statusReason: null
        boardId: 7
        list:
          id: 31
          name: Aguardando envio
        status:
          id: 2
          name: Em negociação
          color: '#F59E0B'
        business:
          id: 9
          name: Varejo
        origin:
          id: 5
          name: Instagram
        assignedTo:
          id: 3
          name: Gabriel Goulart
        contacts:
          - id: 1042
            name: Marina Alves
            number: '5511999999999'
            email: marina@exemplo.com.br
            code: CLI-8842
            cpfCnpj: '12345678909'
            origin: Site
            profilePicUrl: https://cdn.exemplo.com.br/avatar/1042.jpg
            isGroup: false
            instagramUsername: marina.alves
            sourceUrl: https://loja.exemplo.com.br/promo
            sourceId: '23851234567890123'
            headline: Coleção de inverno
            utmSource: instagram
            utmMedium: cpc
            utmCampaign: inverno-2026
            utmId: '6543210987'
            tags:
              - id: 3
                name: Cliente VIP
                color: '#6941C6'
            customFields:
              - key: plano
                value: Ouro
                customFieldId: 91
                name: Plano
                type: select
            lastChannel:
              id: 11
              name: Instagram Loja
              type: instagram
            createdAt: '2026-07-14T13:22:05.412Z'
            updatedAt: '2026-08-18T09:41:17.883Z'
        products:
          - id: 812
            productId: 55
            name: Camiseta preta M
            sku: CAM-PRETA-M
            quantity: 2
            unitPrice: 149.9
            totalPrice: 299.8
        productsTotal: 299.8
        customFields:
          - key: prioridade
            value: Alta
            customFieldId: 77
            name: Prioridade
            type: select
        creationSource: api
        due: '2026-09-15T12:00:00.000Z'
        createdAt: '2026-09-08T14:32:10.000Z'
        updatedAt: '2026-09-08T16:02:44.000Z'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Fixed error code, so your system can handle each case.
              example: ERR_API_FORBIDDEN_SCOPE
            message:
              type: string
            details: {}
    Contact:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
          description: Display name.
        number:
          type: string
        numberCountry:
          type: string
          nullable: true
          description: >-
            Country of the number, as an ISO 3166-1 alpha-2 code. Inferred from
            the country code when the number is saved through the API.
          example: BR
        email:
          type: string
          nullable: true
          example: marina@exemplo.com.br
        code:
          type: string
          nullable: true
        cpfCnpj:
          type: string
          nullable: true
          example: '12345678909'
        origin:
          type: string
          nullable: true
        profilePicUrl:
          type: string
          nullable: true
          example: https://cdn.exemplo.com.br/avatar/1042.jpg
        isGroup:
          type: boolean
          description: The contact is a group, not a person.
        instagramUsername:
          type: string
          nullable: true
          example: marina.alves
        lid:
          type: string
          nullable: true
          example: '178452961234567'
        sourceUrl:
          type: string
          nullable: true
          example: https://loja.exemplo.com.br/promo
        sourceId:
          type: string
          nullable: true
          example: '23851234567890123'
        headline:
          type: string
          nullable: true
          example: Coleção de inverno
        mediaType:
          type: string
          nullable: true
          example: image
        mediaUrl:
          type: string
          nullable: true
          example: https://cdn.exemplo.com.br/anuncios/inverno.jpg
        utmSource:
          type: string
          nullable: true
          example: instagram
        utmMedium:
          type: string
          nullable: true
          example: cpc
        utmCampaign:
          type: string
          nullable: true
          example: inverno-2026
        utmId:
          type: string
          nullable: true
          example: '6543210987'
        fbclid:
          type: string
          nullable: true
          example: IwAR0xYzAbC123
        gclid:
          type: string
          nullable: true
        ctwaClid:
          type: string
          nullable: true
        tags:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
              name:
                type: string
                description: Display name.
              color:
                type: string
                description: Color in hexadecimal, with `#`.
                example: '#6941C6'
        customFields:
          type: array
          description: >-
            Contact custom fields that are filled in. Always included in the
            response, as an empty list when the contact has none.
          items:
            $ref: '#/components/schemas/CustomFieldValue'
        lastChannel:
          type: object
          nullable: true
          properties:
            id:
              type: integer
            name:
              type: string
              description: Display name.
            type:
              type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      example:
        id: 842
        name: Maria Silva
        number: '5511987654321'
        numberCountry: BR
        email: maria.silva@exemplo.com.br
        code: CLI-00842
        cpfCnpj: '12345678909'
        origin: site
        profilePicUrl: https://cdn.exemplo.com/avatars/842.jpg
        isGroup: false
        instagramUsername: maria.silva
        lid: null
        sourceUrl: https://loja.exemplo.com.br/promo
        sourceId: '23851234567890123'
        headline: Coleção de inverno
        mediaType: image
        mediaUrl: https://cdn.exemplo.com/anuncios/inverno.jpg
        utmSource: instagram
        utmMedium: cpc
        utmCampaign: inverno-2026
        utmId: '6543210987'
        fbclid: IwAR0xYzAbC123
        gclid: null
        ctwaClid: null
        tags:
          - id: 3
            name: Cliente VIP
            color: '#6941C6'
        customFields:
          - key: plano
            value: Ouro
            customFieldId: 91
            name: Plano
            type: select
        lastChannel:
          id: 11
          name: Instagram Loja
          type: instagram
        createdAt: '2026-07-14T13:22:05.412Z'
        updatedAt: '2026-08-18T09:41:17.883Z'
    CustomFieldValue:
      type: object
      description: >-
        Value of a custom field, together with the field's definition. This way
        you do not need to call `GET /custom-fields` to find out what field 91
        is.
      properties:
        key:
          type: string
          nullable: true
          description: >-
            Fixed identifier of the field. Use it to point to the field when
            saving values, because the `name` can be renamed in the panel and
            the integration would stop working without warning.
        value:
          type: string
          description: Value filled in for the field, in the format defined by its type.
        customFieldId:
          type: integer
          description: Id of the custom field definition.
          example: 91
        name:
          type: string
          nullable: true
          description: Display name.
        type:
          type: string
          nullable: true
          description: Field type, which defines the format accepted for the value.
      example:
        key: plano
        value: Ouro
        customFieldId: 91
        name: Plano
        type: select
  responses:
    Unauthorized:
      description: Token missing, invalid, revoked or expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ERR_API_UNAUTHORIZED
              message: Token de API ausente ou inválido.
    Forbidden:
      description: >-
        Inactive company, API not enabled on the plan, or insufficient
        permission.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ERR_API_FORBIDDEN_SCOPE
              message: >-
                O token não tem permissão para este método neste módulo. A
                mensagem real nomeia os dois.
    UnprocessableEntity:
      description: >-
        The body is well formed, but a required field is missing or a value is
        not accepted. For example, `application` other than `contact`/`card`, an
        empty `orderedIds` or a blank `name`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ERR_API_VALIDATION
              message: >-
                O parâmetro `application` é obrigatório e aceita "contact" ou
                "card".
    TooManyRequests:
      description: The company exceeded its requests-per-minute limit.
      headers:
        RateLimit-Limit:
          schema:
            type: integer
          description: Requests-per-minute limit.
        RateLimit-Remaining:
          schema:
            type: integer
          description: How many requests are left in the current window.
        RateLimit-Reset:
          schema:
            type: integer
          description: Seconds until the window resets.
        Retry-After:
          schema:
            type: integer
          description: How long to wait before trying again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ERR_API_RATE_LIMIT
              message: Limite de requisições por minuto excedido para esta empresa.
  securitySchemes:
    apiToken:
      type: http
      scheme: bearer
      description: API token in the `sk_live_…` format.

````

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