# Score Contacts by Signal Activity

Score contacts by their active buying signals. Returns the aggregate Signal Score - a [0, 1] value - plus the active signal breakdown per contact.

Accepts up to 100 contacts. Each contact is resolved to a Lusha person ID and company ID server-side (identity only - no PII is revealed) before scoring. Provide one of:
- id (encrypted Lusha contact ID)
- linkedinUrl
- email
- firstName + lastName + (companyName or companyDomain)

Each result is one of:
- A scored entry - signalScore, signalTypes, and noActiveSignals.
- A NOT_FOUND entry - identity resolution failed for the supplied identifier.
- A NO_SCORE entry - the contact resolved, but the scoring engine returned nothing for it.

> Note: A full outage of the identity-resolution provider is never masked as NOT_FOUND - it returns a retryable 502 instead, so callers can retry rather than treating the batch as authoritatively unresolved.

> Billing: 1 credit is charged per scored row via signal_score_contact_reveal. This action is currently limited-availability - while it isn't yet seeded on an account's pricebook, the endpoint stays free (billing.creditsCharged is 0). Error rows (NOT_FOUND / NO_SCORE) are never charged.

Endpoint: POST /v3/contacts/signal-score
Security: ApiKeyAuth

## Request fields (application/json):

  - `contacts` (array, required)

  - `contacts.clientReferenceId` (string)
    Example: "ref-1"

  - `contacts.id` (string)
    Encrypted Lusha contact ID (vN.…).
    Example: "v1.AbCdEfGhIjKlMnOpQrStUvWxYz012345"

  - `contacts.linkedinUrl` (string)
    Example: "https://linkedin.com/in/johndoe"

  - `contacts.email` (string)
    Example: "jane.doe@acme.com"

  - `contacts.firstName` (string)
    Example: "Jane"

  - `contacts.lastName` (string)
    Example: "Doe"

  - `contacts.companyName` (string)
    Example: "Acme Corp"

  - `contacts.companyDomain` (string)
    Example: "acme.com"

## Response 200 fields (application/json):

  - `requestId` (string)
    Example: "5d6f13d2-f6b0-4e55-85d5-04e17f932c1a"

  - `results` (array)

  - `results.clientReferenceId` (string)
    Example: "ref-1"

  - `results.id` (string)
    Encrypted Lusha contact ID for scored entries. On NOT_FOUND, echoes the supplied id, if one was given.
    Example: "v1.AbCdEfGhIjKlMnOpQrStUvWxYz012345"

  - `results.fullName` (string)
    Example: "Jane Doe"

  - `results.company` (object)
    Company the contact was scored at.

  - `results.company.id` (string)
    Example: "v1.6789ZyXwVuTsRqPoNmLkJiHgFeDcBa01"

  - `results.company.name` (string)
    Example: "Acme Corp"

  - `results.company.domain` (string)
    Example: "acme.com"

  - `results.signalScore` (number)
    Aggregate signal score. Absent on error entries.
    Example: 0.3

  - `results.signalTypes` (array)
    Signal types currently active for this contact (canonical camelCase). Absent on error entries.
    Example: ["promotion"]

  - `results.noActiveSignals` (boolean)
    True when the contact resolved and scored but has no active signals (signalScore is 0). Absent on error entries.

  - `results.error` (object)
    Per-item error in a batch response

  - `results.error.code` (string)
    Enum: "NOT_FOUND", "COMPLIANCE_RESTRICTED", "ENRICH_FAILED", "NO_SCORE"

  - `results.error.message` (string)
    Example: "Contact not found"

  - `billing` (object)
    Credit usage summary for a V3 API request

  - `billing.creditsCharged` (integer)
    Total credits charged for this request
    Example: 3

  - `billing.resultsReturned` (integer)
    Number of successful results returned
    Example: 1

## Response 400 fields (application/json):

  - `statusCode` (integer, required)
    HTTP status code
    Example: 400

  - `message` (string, required)
    Error message
    Example: "Validation failed"

  - `errors` (array)
    Detailed error messages (optional, only for validation errors)
    Example: ["entityType must be one of: contact, company"]


