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

> Pushes a contact- or company-level external signal into a Signal Agent.

# Push external signals

export const SnippetObjectReference = ({objectName, objectPath = null}) => {
  const lowerCaseObjectName = objectName.toLowerCase();
  if (lowerCaseObjectName === 'lead' || lowerCaseObjectName === 'leads') {
    return <Note>
        This endpoint uses the <a href={`/api-reference/objects-definitions/${objectPath}`}>{objectName} object</a>. Make sure to also check the <a href={`/api-reference/objects-definitions/${lowerCaseObjectName === 'lead' ? 'contact' : 'lead'}`}>{lowerCaseObjectName === 'lead' ? 'Contact' : 'Lead'} object</a> to understand the distinction between the two.
      </Note>;
  }
  return <Note>
      This endpoint uses the <a href={`/api-reference/objects-definitions/${objectPath}`}>{objectName} object</a>.
    </Note>;
};

<SnippetObjectReference objectName="Signal" objectPath="signal" />

<Note>
  Send `contact` for an `externalSignalContact` agent, or `company` for an `externalSignalCompany` agent — the agent's type decides which block is required. Create the agent first with [Create Signal Agent](/api-reference/endpoints/watch-list/create-watch-list) using `type: externalSignalContact` or `type: externalSignalCompany`. External signals are free (`creditsConsumed` is always `0`) and capped by the agent's daily limit (default 50/day); over the cap, or when no matching entity is found, the signal is returned with `status: "ignored"`.
</Note>


## OpenAPI

````yaml post /watchlist/{watchListId}/external-signals
openapi: 3.0.0
info:
  title: lemlist API
  version: 1.0.0
  description: >-
    Welcome to the lemlist Developer Documentation.


    lemlist is very customizable and open. You'll find on this page all the API
    and integration you can do with lemlist.


    # Rate Limit


    lemlist's API rate limits requests in order to prevent abuse and overload of
    our services.  

    Rate limits are applied on all routes and per API key performing the
    request.  

    The rate limits are **20** requests per **2** seconds.  

    The response provides any information you may need about it:


    | Header | Description |

    | --- | --- |

    | Retry-After | The number of seconds in which you can retry |

    | X-RateLimit-Limit | The maximum requests in that time |

    | X-RateLimit-Remaining | The number of remaining requests you can make |

    | X-RateLimit-Reset | The date when the rate limit will reset |


    _Example of values for the rate limit headers_


    ``` json

    {
        "Retry-After": 2,
        "X-RateLimit-Limit": 20,
        "X-RateLimit-Remaining": 7,
        "X-RateLimit-Reset" : "Tue Feb 16 2021 09:02:42 GMT+0100 (Central European Standard Time)"
    }

     ```

    # Definitions


    ## Team


    A team is the entity of lemlist that can handle users and billing.


    ## Credits


    Credits are the coins a team uses to enrich emails, LinkedIn URLs, etc. via
    the enrich route. Each enrichment feature needs a certain amount of credits
    to run.


    ## User


    You use a user account to connect to lemlist and send messages via the
    connected emails or LinkedIn account.


    ## Campaign


    A campaign is the entity to automate outreach. A campaign has multiple
    sequences composed of steps.


    ## Lead


    A lead is a person that you try to contact via a campaign.


    ## Activity


    An activity is the history of all the steps.


    ## Unsubscribe


    An unsubscribe occurs when a person decides they don't want to receive
    emails from you anymore.


    # Authentication


    All API routes use the dedicated subdomain `api.lemlist.com`.


    lemlist uses API keys to allow access to the API. You can get your lemlist
    API key at our [integration
    page](https://app.lemlist.com/settings/integrations).


    You need to add the `Authorization` header using the `Basic` authentication
    type. `login:password` **where the login is always empty and the password is
    the API key**.


    ⚠️ **Don't forget to add the semicolon (**`:`**) before your API key in curl
    command.**


    > To authorize, use this code: 
      

    ``` shell

    curl https://api.lemlist.com/api/team \
      --user ":YourApiKey"

     ```

    **Make sure to replace** **`YourApiKey`** **with your API key.**


    # Give feedback


    If you want to report a bug, ask for data, or share with us a use case,
    please fill this [form](https://lemlist.typeform.com/to/mfVlkyGf). It will
    help us centralize your needs!
servers:
  - url: https://api.lemlist.com/api
security:
  - basicAuth: []
paths:
  /watchlist/{watchListId}/external-signals:
    post:
      tags:
        - Signal Agents
      summary: Push external signals
      parameters:
        - name: watchListId
          in: path
          required: true
          description: >-
            Id of the Signal Agent to push the signal to. Must be an
            externalSignalContact or externalSignalCompany agent.
          example: wli_ExAmPlE1234567890a
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contact:
                  type: object
                  description: >-
                    The contact the signal is about. Required for
                    externalSignalContact agents; ignored otherwise.
                  required:
                    - linkedinUrl
                  properties:
                    linkedinUrl:
                      type: string
                      description: LinkedIn profile URL. Required.
                      example: https://www.linkedin.com/in/john-doe
                    email:
                      type: string
                      description: Contact email
                      example: john@example.com
                    firstName:
                      type: string
                      description: Contact first name
                      example: John
                    lastName:
                      type: string
                      description: Contact last name
                      example: Doe
                company:
                  type: object
                  description: >-
                    The company the signal is about. Required for
                    externalSignalCompany agents; ignored otherwise.
                  required:
                    - domain
                    - name
                  properties:
                    domain:
                      type: string
                      description: Company domain. Required.
                      example: acme.com
                    name:
                      type: string
                      description: Company name. Required.
                      example: Acme Inc
                    linkedinUrl:
                      type: string
                      description: LinkedIn company URL
                      example: https://www.linkedin.com/company/acme
                customFields:
                  type: object
                  description: >-
                    Optional key/value metadata stored on the signal. Max 20
                    keys; all values must be strings.
                  additionalProperties:
                    type: string
                  example:
                    plan: enterprise
                    source: webinar
      responses:
        '200':
          description: >-
            Signal processed or ignored. `status` is `processed` when a signal
            was created, or `ignored` when no matching entity was found or the
            agent's daily limit was reached. External signals are free, so
            `creditsConsumed` is always 0.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalSignalPushResponse'
              examples:
                processed:
                  value:
                    status: processed
                    signalId: wls_ExAmPlE1234567890a
                    creditsConsumed: 0
                    entity:
                      type: contact
                      id: lea_ExAmPlE1234567890a
                      enriched: true
                ignoredNoMatch:
                  value:
                    status: ignored
                    reason: no_entity_match
                    creditsConsumed: 0
                ignoredDailyLimit:
                  value:
                    status: ignored
                    reason: daily_limit_reached
                    creditsConsumed: 0
        '400':
          description: Validation error - invalid contact, company, or custom fields
          content:
            text/plain:
              examples:
                invalidContact:
                  value: >-
                    Contact must have a valid LinkedIn profile URL (e.g.
                    https://www.linkedin.com/in/...)
                invalidCompany:
                  value: >-
                    Company must have a domain and a name; linkedinUrl (when
                    provided) must be a valid LinkedIn company URL (e.g.
                    https://www.linkedin.com/company/...)
                invalidCustomFields:
                  value: Custom fields must have 20 keys or less with string values
        '401':
          description: Unauthorized - invalid or missing API key
          content:
            text/plain:
              example: Unauthorized
        '404':
          description: Watch list not found or not configured for external signals
          content:
            text/plain:
              example: Watch list not found or not configured for external signals
        '500':
          description: Internal server error
          content:
            text/plain:
              example: Internal server error
components:
  schemas:
    ExternalSignalPushResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - processed
            - ignored
          description: '`processed` when a signal was created, `ignored` otherwise'
        signalId:
          type: string
          description: Id of the created signal. Present when status is processed.
          example: wls_ExAmPlE1234567890a
        reason:
          type: string
          enum:
            - no_entity_match
            - daily_limit_reached
          description: Why the signal was ignored. Present when status is ignored.
        creditsConsumed:
          type: integer
          description: Always 0 - external signals are free.
          example: 0
        entity:
          type: object
          description: The matched entity. Present when status is processed.
          properties:
            type:
              type: string
              enum:
                - contact
                - company
            id:
              type: string
              description: Entity id or watch key
              example: lea_ExAmPlE1234567890a
            enriched:
              type: boolean
              description: Whether the entity was enriched from lemlist data
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

````