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

# Mark a contact dedup review as merged

> Marks the review as merged, merging the source contact into the candidate per the optional resolution payload, recording the resolving user, and writing an audit log entry. Emits socket updates so other clients refresh their dedup queues.



## OpenAPI

````yaml /api-reference/openapi.yaml patch /api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge
openapi: 3.0.3
info:
  title: Tether Relay and Tether API
  version: 1.0.0
  description: >-
    Route-derived OpenAPI contract generated from tether-relay backend sources.
    Regenerate with scripts/sync-openapi-from-backend.mjs.
servers:
  - url: https://your-instance.example.com
    description: Production
  - url: http://localhost:2212
    description: Local API service
security: []
tags:
  - name: AI
  - name: Applications
  - name: Approval
  - name: Auth
  - name: Automations
  - name: Calls
  - name: Campaigns
  - name: Contact Analytics
  - name: Contact Metrics
  - name: Contact Notes
  - name: Contacts
  - name: Conversation Monitor
  - name: Conversations
  - name: Departments
  - name: Email
  - name: Escalation Dashboard
  - name: Event Logs
  - name: Google Sheets
  - name: Marketplace
  - name: Messages
  - name: Notification Sounds
  - name: Notifications
  - name: Org Snapshots
  - name: Organizations
  - name: Outreach
  - name: Outreach Metrics
  - name: Outreach Sources
  - name: Pipelines
  - name: Processes
  - name: Prompts
  - name: Reminders
  - name: Sms
  - name: Templates
  - name: Traces
  - name: Training
  - name: Upload
  - name: User Snapshots
  - name: Users
  - name: Vertical
  - name: Webchats
  - name: Webhook
paths:
  /api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge:
    patch:
      tags:
        - Organizations
      summary: Mark a contact dedup review as merged
      description: >-
        Marks the review as merged, merging the source contact into the
        candidate per the optional resolution payload, recording the resolving
        user, and writing an audit log entry. Emits socket updates so other
        clients refresh their dedup queues.
      operationId: patch_organizations_organizationId_contact_dedup_reviews_reviewId_merge
      parameters:
        - in: path
          name: organizationId
          required: true
          schema:
            type: string
        - in: path
          name: reviewId
          required: true
          schema:
            type: string
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactDedupReviewResolutionRequest'
      responses:
        '200':
          description: Contact dedup review marked as merged
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactDedupReviewMutationResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationErrorResponse'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationErrorResponse'
        '404':
          description: Contact dedup review not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    ContactDedupReviewResolutionRequest:
      type: object
      properties:
        resolution:
          type: object
          additionalProperties: true
          description: >-
            Freeform resolution payload recorded on the review; for merges, may
            include fieldChoices (source/candidate per field) and other
            reviewer-chosen metadata persisted with the merge audit entry.
      additionalProperties: true
      example:
        resolution:
          keepContactId: 5f7b1c2e8a1d4e0012c3b4a5
          mergedFields:
            - email
            - phoneNumber
    ContactDedupReviewMutationResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
        message:
          type: string
        data:
          $ref: '#/components/schemas/ContactDedupReview'
      required:
        - success
        - message
        - data
      additionalProperties: true
      example:
        success: true
        message: Contact dedup review marked as merged
        data:
          _id: 5f7b1c2e8a1d4e0012c3b4b0
          organizationId: 5f7b1c2e8a1d4e0012c3b400
          reviewSource: fuzzy_match
          status: merged
          resolvedAt: '2026-05-18T14:35:00.000Z'
    OrganizationErrorResponse:
      type: object
      properties:
        error:
          type: string
        details:
          type: string
      additionalProperties: true
      example:
        error: Organization not found
        details: No organization exists with the provided id
    ContactDedupReview:
      type: object
      properties:
        _id:
          type: string
        organizationId:
          type: string
        sourceContactId:
          oneOf:
            - type: string
            - $ref: '#/components/schemas/ContactDedupReviewContact'
        candidateContactId:
          oneOf:
            - type: string
            - $ref: '#/components/schemas/ContactDedupReviewContact'
        reviewSource:
          type: string
          enum:
            - fuzzy_match
            - phone_conflict
        status:
          type: string
          enum:
            - needs_review
            - merged
            - kept_separate
        score:
          type: number
        thresholdSnapshot:
          type: object
          additionalProperties: true
        fieldBreakdown:
          type: object
          additionalProperties: true
        sourceSnapshot:
          type: object
          additionalProperties: true
        candidateSnapshot:
          type: object
          additionalProperties: true
        resolution:
          type: object
          additionalProperties: true
        resolvedBy:
          oneOf:
            - type: string
            - $ref: '#/components/schemas/ContactDedupReviewResolvedBy'
        resolvedAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      required:
        - reviewSource
        - status
      additionalProperties: true
      example:
        _id: 5f7b1c2e8a1d4e0012c3b4b0
        organizationId: 5f7b1c2e8a1d4e0012c3b400
        sourceContactId: 5f7b1c2e8a1d4e0012c3b4a5
        candidateContactId: 5f7b1c2e8a1d4e0012c3b4a7
        reviewSource: fuzzy_match
        status: needs_review
        score: 86
        thresholdSnapshot:
          thresholdPercent: 90
          reviewThresholdPercent: 70
        fieldBreakdown:
          firstName: 100
          lastName: 80
          email: 75
        createdAt: '2026-05-18T14:30:00.000Z'
        updatedAt: '2026-05-18T14:30:00.000Z'
    ContactDedupReviewContact:
      type: object
      properties:
        _id:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        email:
          type: string
        phoneNumber:
          oneOf:
            - type: string
            - type: array
              items:
                $ref: '#/components/schemas/ContactPhoneNumber'
        secondaryPhoneNumber:
          type: array
          items:
            type: string
        isProvisional:
          type: boolean
      additionalProperties: true
      example:
        _id: 5f7b1c2e8a1d4e0012c3b4a5
        firstName: Jane
        lastName: Doe
        email: jane.doe@acme.example
        phoneNumber:
          - value: '+14165550100'
            isPrimary: true
        secondaryPhoneNumber:
          - '+14165550101'
        isProvisional: false
    ContactDedupReviewResolvedBy:
      type: object
      properties:
        _id:
          type: string
        fullName:
          type: string
        email:
          type: string
      additionalProperties: true
      example:
        _id: 5f7b1c2e8a1d4e0012c3b4a6
        fullName: Ops Admin
        email: ops@acme.example
    ContactPhoneNumber:
      type: object
      properties:
        value:
          type: string
        isPrimary:
          type: boolean
      required:
        - value
      additionalProperties: true
      example:
        value: '+14165550100'
        isPrimary: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````