{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/anjal-app/json-schema/anjal-app-linked-in-signal-schema.json",
  "title": "LinkedInSignal",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/anjal-app-openapi.yaml#/components/schemas/LinkedInSignal",
  "type": "object",
  "required": [
    "id",
    "kind",
    "name",
    "cadence",
    "filterMinIntent",
    "intentDescription",
    "enabled"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "kind": {
      "type": "string",
      "enum": [
        "keyword",
        "engagement",
        "job_change_watchlist"
      ],
      "description": "Acquisition strategy for this signal:\n  - keyword: poll LinkedIn search for the saved query.\n  - engagement: poll a tracked profile/company's recent posts and fire on engagers.\n  - job_change_watchlist: poll a list of profiles weekly and fire on role/company changes.\n"
    },
    "name": {
      "type": "string"
    },
    "query": {
      "type": [
        "string",
        "null"
      ],
      "description": "Required for kind=keyword; null otherwise."
    },
    "target": {
      "type": [
        "object",
        "null"
      ],
      "description": "Engagement signals only — the resolved actor target.",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "profile",
            "company"
          ]
        },
        "url": {
          "type": "string"
        },
        "urn": {
          "type": "string",
          "description": "Resolved urn:li:fsd_profile:* or urn:li:fsd_company:*."
        },
        "label": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "lastSeenPostUrn": {
      "type": [
        "string",
        "null"
      ],
      "description": "Engagement signals only — watermark of the most recent post processed. We only fire on engagers of posts newer than this."
    },
    "watchlistCount": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Watchlist signals only — number of profiles being tracked."
    },
    "sessionId": {
      "type": [
        "string",
        "null"
      ],
      "description": "null = auto-distribute polling across all healthy LinkedIn\nsessions for this tenant (recommended). Specific id = pin\nthe signal to that account so all polls come from it.\n"
    },
    "cadence": {
      "type": "string",
      "enum": [
        "daily",
        "every_12h",
        "every_6h",
        "manual"
      ]
    },
    "webhookUrl": {
      "type": [
        "string",
        "null"
      ]
    },
    "webhookSecret": {
      "type": [
        "string",
        "null"
      ],
      "description": "Returned only on creation. Verify with HMAC-SHA256."
    },
    "filterMinIntent": {
      "type": "string",
      "enum": [
        "low",
        "medium",
        "high"
      ]
    },
    "intentDescription": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Plain-English firing rule the LLM classifier uses as the\nauthoritative definition of what should fire. Example: \"Flag as\nready when the author is a founder/operator complaining about\ncold email — skip vendors, agencies, and content marketers.\"\nThe keyword is only a coarse pre-filter; this rule decides\nengage=true/false and the cited reason on every match.\n"
    },
    "enabled": {
      "type": "boolean"
    },
    "lastPolledAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "nextPollAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "lastError": {
      "type": [
        "string",
        "null"
      ]
    },
    "lastErrorCode": {
      "type": [
        "string",
        "null"
      ]
    },
    "lastErrorAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "matchesCount": {
      "type": "integer"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}