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

# Send Opportunity Alert

> Sends an in-app notification to the agent(s) assigned to the given lead, representing a buyer/seller activity signal (e.g. viewed a listing, saved a search, requested CMA). Certain notificationType values also trigger SMS and Email delivery.

**Use case:** a partner system observes a user action on its own site and wants that action to surface as an opportunity in the assigned agent's Lofty inbox.

## Delivery channels

| Channel | Trigger |
|---|---|
| In-app push | All notificationType values |
| SMS + Email | Browse (11/48/138), Saved listing (9/52/136), Saved search (27/140), Mortgage calculator (89), Return-to-site (166) |

If the lead belongs to a lead pond, the notification is broadcast to all pond members instead of the single assignee.

## Important notes

- The leadId **must** belong to the caller's own team.
- Agents whose team has the OPPORTUNITY resource disabled are silently skipped.
- This endpoint is **not idempotent**. Repeated calls produce repeated deliveries.
- The `data` field in the response is a best-effort success hint, not a strict delivery confirmation. See the 200 response description for details.



## OpenAPI

````yaml openapi/openapi.json POST /v1.0/agent/send-notification
openapi: 3.0.1
info:
  title: Lofty Service Open APIs
  description: Lofty service API description
  version: '1.0'
servers:
  - url: https://api.lofty.com
security: []
tags:
  - name: Tasks & Appointments V2
    description: >-
      Unified V2 API for lead tasks and appointments: list, create, read,
      update, finish, unfinish and delete. Tasks and appointments share the same
      taskId namespace; each endpoint resolves the target by ID regardless of
      underlying type.
  - name: Opportunity
    description: Operations about opportunity
  - name: Communication V2
    description: >-
      Fetch a single communication record (text / email / call) by its
      communication ID. Closes the webhook follow-up gap where only list-by-lead
      endpoints existed for text and email.
  - name: Vendor
    description: >-
      Team vendor directory: team members, sub-accounts and associated agents
      within the caller's team.
  - name: Lead Routing
    description: >-
      Lead routing configuration: read and update routing rules and default
      (supplement) rules per business type, and list the members and roles
      available for assignment.
  - name: Lead Activity V2 API
    description: >-
      Unified lead activity timeline: returns call, text and email activities
      for a lead in chronological order, including both auto-captured and
      agent-logged entries.
  - name: Tasks & Appointments
    description: >-
      Agent tasks and lead appointments. Supports listing a lead's appointments,
      listing / reading / creating / updating / deleting tasks on a lead.
  - name: Transactions V2
    description: V2 transaction APIs.
  - name: Lead Manual Log
    description: >-
      Agent-recorded log of communications that happened outside the Lofty CRM
      (calls placed on a personal line, emails sent from another mailbox, SMS
      sent from another device). Three channels are supported: logCall,
      logEmail, logText. Direction fields are recorded from the agent's point of
      view: 'outbound' = agent -> lead, 'inbound' = lead -> agent. Persistence
      is asynchronous: a POST returns the new entry's ID once the write is
      enqueued, and the entry becomes readable after a short delay.
  - name: Calls
    description: >-
      Calls placed or received through the Lofty dialer. Supports fetching a
      recording URL, retrieving a single call record, and listing calls attached
      to a lead.
  - name: Listing V2
    description: Listing search V2
  - name: Agent User
    description: >-
      Agent onboarding and team directory operations. Create a new agent under
      the caller's team and attach tags to existing agents.
  - name: Sales Agents V2
    description: >-
      Sales Agent (AI Assistant) management: read the caller's assistant and
      quota, query leads followed by AI, mute leads, manage working-pool
      membership and plan tasks, and update Sales Agent settings.
  - name: Calendar V2 API
    description: >-
      Unified V2 API for tasks and appointments on a lead: create, update,
      delete, finish, unfinish, query a paginated list, and find available
      meeting slots. Calendar IDs returned by POST /v2.0/calendar are composite
      strings of the form '<numericId>-task' or '<numericId>-appointment' and
      must be sent back as-is to the per-entry endpoints.
  - name: Lead System Logs
    description: Query a lead's system log.
  - name: Lead Transaction
    description: Operations about leads
  - name: Notifications V2
    description: Operations for sending notifications to agents
  - name: Notes
    description: >-
      Free-text notes attached to a lead. Supports create, list, get-by-id,
      update and delete. Notes may be pinned to surface them at the top of the
      lead's timeline. System-generated notes (automated activity) are included
      on the list endpoint only when explicitly requested.
  - name: Listing
    description: >-
      Listing data access: retrieve published listings for a site feed (XML),
      and search active / sold listings by agent, office or MLS id.
  - name: Intelligent Features
    description: AI-powered features for lead analysis and communication
  - name: Leads
    description: >-
      Lead lifecycle operations: create / read / update / delete a lead, search
      leads by stage, source, tag, create time or update time, place an inquiry
      or property on a lead, list lead activities, resolve assignee by lead
      info, and handle Brokermint contact callbacks.
  - name: Members
    description: >-
      Team member directory: look up members by user ID, by account (email), or
      list all members of the caller's team. Also supports retrieving the
      current user's profile.
  - name: Team Features
    description: >-
      Team-scoped metadata: lead tags, custom fields, and lead ponds. Supports
      listing existing entries, adding a new custom field, and retrieving a
      specific lead pond.
  - name: Agent Organization
    description: >-
      Team organizational structure: read the caller's organization info, manage
      company and office records, and list permission profiles available to the
      team.
  - name: Communication
    description: >-
      Lead communication history and outbound messaging: list call / email /
      text history for a lead, search communications for an agent, and send SMS
      or email to a lead.
  - name: Webhooks
    description: >
      Use webhooks to be notified about events that happen in a lofty account.


      Supported webhook event types (listId):


      | listId | Event Type | Description |

      |--------|-----------|-------------|

      | 1 | Agent Info | Agent created or updated |

      | 2 | Lead Info | Lead created, updated, or deleted |

      | 3 | Lead Activity | Lead site activity (e.g. SiteBrowse, SiteFavorite,
      SiteSearch) |

      | 4 | Listing Alert | Listing alert changed |

      | 5 | Transaction | Transaction created, updated, or deleted |

      | 6 | Call | Call event (MANUAL and LOGGED only, excludes AUTO) |

      | 7 | Email | Email event (MANUAL and LOGGED only, excludes AUTO) |

      | 8 | Text | Text message event (MANUAL and LOGGED only, excludes AUTO) |

      | 9 | Note | Note created, updated, or deleted |

      | 10 | Task | Task created, updated, finished, or deleted |

      | 11 | Appointment | Appointment created, updated, finished, or deleted |

      | 12 | Pipeline Change | Lead pipeline stage changed |


      ### Notification Recipient Rules


      Here "team" means the entire Lofty client account (the organization), not
      the Lofty "Team add-on" product.


      Which subscribed users receive a callback depends on the subscription's
      delivery mode (`permissionMode`). In both modes, only users in the lead's
      account (team) who have subscribed to the event type are considered.


      **Assignment-based delivery — `permissionMode: 0` (default)**


      A subscriber receives the callback only for leads assigned to them or that
      they administer:

      - If the lead is a **hidden lead**, only the **assigned agent** receives
      the notification.

      - Otherwise, the subscriber receives it if they are the **assigned agent**
      of the lead, or a **Company Owner** or **Company Admin**.

      - All other subscribers do **not** receive the notification.


      **Ownership-based delivery — `permissionMode: 1`**


      A subscriber receives the callback for any lead they manage, regardless of
      who it is assigned to:

      - Every assignment-based case above still applies (assigned agent, Company
      Owner / Company Admin).

      - In addition, the subscriber receives the callback for any lead within
      their **ownership scope** — a lead owned by their **team** or **office**,
      or **personally owned** by them — even if it is assigned to someone else.

      - Hidden leads are still delivered only to users who manage them.


      Ownership-based mode is intended for team/account-level integrations that
      must cover every lead in their scope, not only assigned leads. Set
      `permissionMode` when creating the subscription (POST /v1.0/webhook); it
      defaults to `0`, so existing subscriptions are unaffected.


      ### Delivery Timing


      Webhooks are typically delivered within **1 minute** of the event being
      triggered. During periods of high traffic, delivery may be delayed, but
      will always be sent within **5 minutes**.


      For detailed callback payload structures, see [Webhook Event
      Payloads](/concepts/webhooks#event-payloads).
paths:
  /v1.0/agent/send-notification:
    post:
      tags:
        - Opportunity
      summary: Send Opportunity Alert
      description: >-
        Sends an in-app notification to the agent(s) assigned to the given lead,
        representing a buyer/seller activity signal (e.g. viewed a listing,
        saved a search, requested CMA). Certain notificationType values also
        trigger SMS and Email delivery.


        **Use case:** a partner system observes a user action on its own site
        and wants that action to surface as an opportunity in the assigned
        agent's Lofty inbox.


        ## Delivery channels


        | Channel | Trigger |

        |---|---|

        | In-app push | All notificationType values |

        | SMS + Email | Browse (11/48/138), Saved listing (9/52/136), Saved
        search (27/140), Mortgage calculator (89), Return-to-site (166) |


        If the lead belongs to a lead pond, the notification is broadcast to all
        pond members instead of the single assignee.


        ## Important notes


        - The leadId **must** belong to the caller's own team.

        - Agents whose team has the OPPORTUNITY resource disabled are silently
        skipped.

        - This endpoint is **not idempotent**. Repeated calls produce repeated
        deliveries.

        - The `data` field in the response is a best-effort success hint, not a
        strict delivery confirmation. See the 200 response description for
        details.
      operationId: sendOpportunityNotification
      parameters:
        - name: Authorization
          in: header
          description: Bearer [access_token]
          required: true
          schema:
            type: string
        - name: Content-Type
          in: header
          description: application/json
          required: true
          schema:
            type: string
          example: application/json
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpportunityNotificationRequest'
        required: true
      responses:
        '200':
          description: >-
            Request accepted. Response body = {status:{code:0,msg:"success"},
            data:<bool>}. data=true  => notification(s) dispatched to at least
            one assignee (non-pond path). data=false => one of the
            silent-failure conditions: leadId=0, notificationType=null, lead not
            found, no agent-role assignee, or the lead is a lead-pond lead
            (where broadcast is still triggered but the API returns false due to
            a known quirk). Callers SHOULD NOT rely on data=true/false as a
            strict delivery confirmation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendOpportunityNotificationResponse'
        '400':
          description: >-
            Invalid token / rate-limited / package quota exceeded (handled by
            the common filter chain before reaching this endpoint; see
            RateLimitFilter / PackageLimitFilter).
          content:
            application/json:
              schema:
                type: string
        '500':
          description: Internal error (error code 20005).
          content:
            application/json:
              schema:
                type: string
components:
  schemas:
    OpportunityNotificationRequest:
      required:
        - leadId
        - notificationType
      type: object
      properties:
        leadId:
          type: integer
          description: Lead ID. Must belong to the caller's team.
          format: int64
          example: 100001
        description:
          type: string
          description: >-
            Free-text description shown in the notification body. description
            and link form a combo; both must be non-empty for the details block
            to render.
          example: 123 Main St, San Francisco, CA 94102
        link:
          type: string
          description: >-
            Companion URL to description (see description field). Typically a
            listing / search / CMA URL.
          example: https://example.com/listing/123
        message:
          type: string
          description: >-
            Optional free-text message. Rendered only for notificationType
            values that carry a leave-message context (e.g. 65); ignored by all
            other types.
          example: I'd like to schedule a tour this weekend.
        notificationType:
          type: integer
          description: >-
            Opportunity trigger type. Must match one of the supported activity
            codes.


            Site-origin values:
             9  = Saved a listing
             10 = Searched
             11 = Viewed a listing
             27 = Saved a search
             46 = Requested to sell a house
             47 = Requested home evaluation
             65 = Left a message
             66 = Requested a showing
             89 = Used mortgage calculator
            162 = Requested CMA

            164 = Requested financing options


            NewHome-origin equivalents:
             48 = Browsed a home
             50 = Searched a home
             52 = Favorited a home

            CApp-origin equivalents:

            136 = Favorited

            137 = Searched

            138 = Browsed

            139 = Showing request

            140 = Saved search

            141 = House evaluation


            Other:

            165 = Re-inquired on text code

            166 = Back to site (view a listing)

            167 = Submitted a form

            168 = Viewed CMA
          format: int32
          example: 11
          enum:
            - 9
            - 10
            - 11
            - 27
            - 46
            - 47
            - 48
            - 50
            - 52
            - 65
            - 66
            - 89
            - 136
            - 137
            - 138
            - 139
            - 140
            - 141
            - 162
            - 164
            - 165
            - 166
            - 167
            - 168
    SendOpportunityNotificationResponse:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/SendOpportunityNotificationResponse.Status'
        data:
          type: boolean
          description: >-
            Rough success flag. true = notification dispatched. false =
            silent-failure condition (missing lead, no assignee) or
            pond-broadcast quirk (see endpoint description). Callers should not
            treat this as a strict delivery confirmation.
          example: true
      description: Wrapped response for POST /v1.0/agent/send-notification.
    SendOpportunityNotificationResponse.Status:
      type: object
      properties:
        code:
          type: integer
          description: Response code; 0 indicates success.
          format: int32
          example: 0
        msg:
          type: string
          description: Response message.
          example: success
      description: Status envelope; code=0 indicates the request was processed.

````