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

# Update a sales opportunity

> Requires `crm:sales:write`. Edit one field or stage, or restore AI control. Requires current revision; conflicts return 409. Closed opportunities cannot reopen. Uses the published sales CRM, not legacy lead-stage classification.



## OpenAPI

````yaml /openapi.json patch /crm/sales/opportunities/{opportunityId}
openapi: 3.0.3
info:
  title: Visito M2M API
  version: 1.0.0
  description: >-
    Tenant-scoped server-to-server API for channels, conversations, commerce,
    custom AI tools, and WhatsApp templates. Send operations are asynchronous
    and return queued acknowledgements. Expansion adds conversation controls,
    knowledge, sales opportunities, delivery status, reporting, and signed
    webhooks.
servers:
  - url: https://platform-api.visitoai.com/m2m/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Channels
  - name: Conversations
  - name: Commerce
  - name: Custom tools
  - name: WhatsApp templates
  - name: Properties
  - name: Knowledge
  - name: Sales CRM
  - name: Delivery
  - name: Reporting
  - name: Webhooks
paths:
  /crm/sales/opportunities/{opportunityId}:
    patch:
      tags:
        - Sales CRM
      summary: Update a sales opportunity
      description: >-
        Requires `crm:sales:write`. Edit one field or stage, or restore AI
        control. Requires current revision; conflicts return 409. Closed
        opportunities cannot reopen. Uses the published sales CRM, not legacy
        lead-stage classification.
      operationId: m2mPatchCrmSalesOpportunitiesOpportunityid
      parameters:
        - name: opportunityId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SalesOpportunityPatch'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SalesOpportunityResponse'
        default:
          $ref: '#/components/responses/Error'
components:
  schemas:
    SalesOpportunityPatch:
      type: object
      properties:
        revision:
          type: integer
          minimum: 0
        fieldId:
          type: string
        value:
          description: Value matching the published field type; null clears and locks it.
        stageId:
          type: string
        restoreAi:
          type: boolean
      required:
        - revision
    SalesOpportunityResponse:
      type: object
      properties:
        opportunity:
          $ref: '#/components/schemas/SalesOpportunity'
        activity:
          type: array
          items:
            type: object
            description: Latest 50 crm_sales_audit records for this opportunity.
    SalesOpportunity:
      type: object
      properties:
        opportunityId:
          type: string
        leadId:
          type: string
        conversationId:
          type: string
        displayName:
          type: string
        channel:
          type: string
        version:
          type: integer
        revision:
          type: integer
        stageId:
          type: string
        stageLocked:
          type: boolean
        status:
          type: string
          enum:
            - open
            - won
            - lost
        summary:
          type: string
        values:
          type: object
          additionalProperties:
            type: object
        createdAt:
          type: string
        updatedAt:
          type: string
        closedAt:
          type: string
      required:
        - opportunityId
        - revision
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              example: M2M_AUTH_INSUFFICIENT_SCOPE
            message:
              type: string
            details:
              type: object
              additionalProperties: true
      example:
        error:
          code: M2M_AUTH_INSUFFICIENT_SCOPE
          message: M2M credential does not have required scope.
          details:
            requiredScopes:
              - conversations:write
            missingScopes:
              - conversations:write
  responses:
    Error:
      description: Structured error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Visito M2M API key
      description: Server-side tenant-scoped credential created from Build > API Keys.

````