Anjal LinkedIn — Searches API

Deterministic historical search across past-24h | past-week | past-month. Synchronous — returns the full hit list inline with the same structured output shape as signals (post + author + classification + cited reason). The plain-English firing rule filters to *exactly* what the buyer means; the keyword is a coarse pre-filter. Persisted server-side so the result set can be re-opened without spending another LinkedIn quota.

Operations 3

GET /linkedin/searches List past searches #
POST /linkedin/searches Run a historical search #
GET /linkedin/searches/{id} Fetch a past search + its results #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/anjal-app:anjal-app-linkedin-searches-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

anjal-app-linkedin-searches-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Anjal LinkedIn — Searches API
  version: 1.0.0
  description: 'Anjal is a multi-tenant email API for AI agents.


    Create inboxes on the default `@send.anjal.app` domain or your own custom

    domains, send and receive mail, manage drafts, subscribe to real-time

    events over WebSocket, and isolate resources across workspaces so your

    reseller customers can serve their own end-customers under a single

    billing relationship.


    Install the TypeScript SDK: `npm install anjal`

    (npm)


    MCP server for Claude Desktop / Cursor: `npx -y anjal-mcp`

    (npm)


    ## Authentication


    Every request is authenticated with the `X-API-Key` header (or

    `Authorization: Bearer `). Four key prefixes, each with increasing

    scope:


    | Prefix | Scope | Use it for |

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

    | `sa_...` | Super admin | Tenant lifecycle (platform operator) |

    | `tk_...` | Tenant master | Everything in your tenant across workspaces |

    | `wk_...` | Workspace master | One workspace only |

    | `ak_...` | Inbox (agent) scoped | One inbox — its messages, drafts, lists |


    ## Resource hierarchy


    ```

    Tenant (billing root)

    └── Workspace (isolation container)

    ├── Inboxes

    │ ├── Messages / Threads / Attachments

    │ ├── Drafts

    │ └── Lists

    └── Domains

    ```


    ## Sending mail


    Mail is sent via `POST /v1/inboxes/{id}/send`. Replies go through

    `/reply/{messageId}`, reply-all through `/reply-all/{messageId}`, and

    forwards through `/forward/{messageId}`. The `From` header always uses

    the inbox''s **primary alias** — add a custom-domain address with

    `POST /v1/inboxes/{id}/addresses` to change it.


    ### Safe retries (Idempotency-Key)


    Every send endpoint (`/send`, `/reply`, `/reply-all`, `/forward` and

    `POST /v1/inboxes/{id}/drafts/{did}/send`) accepts an `Idempotency-Key`

    header. Send a unique value (a UUID works) and retry freely: the first

    request sends and stores its response; a retry with the same key and the

    identical request returns that stored response with the header

    `Idempotent-Replayed: true` and sends nothing.


    | Situation | Result |

    |---|---|

    | Same key, different request (body, inbox or endpoint) | `409 IDEMPOTENCY_KEY_REUSED` |

    | Same key while the first request is still running | `409 IDEMPOTENCY_IN_PROGRESS` |

    | Header present but blank, or longer than 255 characters | `400 IDEMPOTENCY_KEY_INVALID` |

    | The first send failed (non-2xx) | The key is freed; retry with the same key |


    Keys are scoped to your account and expire after 24 hours.


    ### Labels, open tracking, scheduled send


    - **Labels**: pass `labels` (array, or a comma-separated string) on any

    send, reply, reply-all, forward or draft. Change them later with

    `PATCH /v1/inboxes/{id}/messages/{messageId}` or

    `PATCH /v1/inboxes/{id}/threads/{threadId}`, and filter lists with

    `?labels=a,b`. Labels are stored lowercase and deduplicated; at most 32

    per message, each at most 64 characters, no commas.

    - **Open tracking**: `trackOpens: true` on a send with an HTML body adds a

    1x1 pixel (the stored copy never contains it). The first open fires

    `message.opened`. Opens are a hint, not proof: Apple Mail Privacy

    Protection fetches images on delivery, and clients that block images

    never report an open.

    - **Scheduled send**: set `sendAt` on a draft and Anjal sends it at that

    time. See the Drafts endpoints.

    - **Delivery status**: sent messages carry `deliveryStatus`

    (`delivered`, `bounced`, `complained` or `rejected`; null until known)

    and `deliveredAt`.


    ## Receiving mail


    Inbound mail arrives via SMTP on the default domain or any verified

    custom domain. Subscribe to delivery events either by registering a

    webhook (`POST /v1/webhooks`) or by opening a WebSocket

    (`wss://anjal.app/v1/ws`) — useful for in-line 2FA flows where

    the agent doesn''t have a public webhook receiver.'
servers:
- url: https://anjal.app
  description: Production
security:
- apiKeyHeader: []
tags:
- name: LinkedIn — Searches
  description: 'Deterministic historical search across past-24h | past-week |

    past-month. Synchronous — returns the full hit list inline with the

    same structured output shape as signals (post + author +

    classification + cited reason). The plain-English firing rule

    filters to *exactly* what the buyer means; the keyword is a coarse

    pre-filter. Persisted server-side so the result set can be re-opened

    without spending another LinkedIn quota.'
paths:
  /linkedin/searches:
    get:
      tags:
      - LinkedIn — Searches
      summary: List past searches
      description: Audit log of historical searches run by this tenant, newest first.
      operationId: linkedinListSearches
      parameters:
      - in: query
        name: limit
        schema:
          type: integer
          default: 50
          maximum: 100
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  searches:
                    type: array
                    items:
                      $ref: '#/components/schemas/LinkedInSearch'
    post:
      tags:
      - LinkedIn — Searches
      summary: Run a historical search
      description: 'Synchronous keyword search across the past 24 hours, week, or month.

        Returns the full hit list inline. Use this for one-shot lookups; for

        continuous monitoring use POST /v1/linkedin/signals.'
      operationId: linkedinRunSearch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - query
              - intentDescription
              properties:
                sessionId:
                  type: string
                  nullable: true
                  description: Omit or send null to auto-distribute. Pass a session id to pin.
                query:
                  type: string
                  minLength: 2
                  maxLength: 500
                lookback:
                  type: string
                  enum:
                  - past-24h
                  - past-week
                  - past-month
                  default: past-week
                minIntent:
                  type: string
                  enum:
                  - low
                  - medium
                  - high
                  nullable: true
                  description: Filter results below this intent level. Omit for unfiltered.
                intentDescription:
                  type: string
                  minLength: 1
                  maxLength: 2000
                  description: 'Plain-English firing rule the LLM classifier treats as

                    the authoritative definition of what should fire (same

                    semantics as on signals). The keyword is a coarse

                    pre-filter; this rule decides engage and the cited

                    reason on every result.

                    '
                limit:
                  type: integer
                  minimum: 1
                  maximum: 100
                  default: 50
      responses:
        '200':
          description: Search ran successfully. results may be empty.
          content:
            application/json:
              schema:
                type: object
                properties:
                  search:
                    $ref: '#/components/schemas/LinkedInSearch'
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/LinkedInSearchResult'
        '404':
          description: LinkedIn session not found or inactive.
        '429':
          description: LinkedIn rate-limited this session. The search row is persisted with errorCode=LINKEDIN_RATE_LIMITED.
        '502':
          description: LinkedIn returned an unexpected error. The search row is persisted with the error captured.
  /linkedin/searches/{id}:
    get:
      tags:
      - LinkedIn — Searches
      summary: Fetch a past search + its results
      description: Re-open a persisted search without spending another LinkedIn quota.
      operationId: linkedinGetSearch
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  search:
                    $ref: '#/components/schemas/LinkedInSearch'
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/LinkedInSearchResult'
        '404':
          description: Not found.
components:
  schemas:
    LinkedInSearch:
      type: object
      required:
      - id
      - query
      - lookback
      - intentDescription
      - resultCount
      - createdAt
      properties:
        id:
          type: string
        sessionId:
          type: string
          nullable: true
          description: The LinkedIn session that actually ran the search (the router's pick when the caller didn't pin).
        query:
          type: string
        lookback:
          type: string
          enum:
          - past-24h
          - past-week
          - past-month
        minIntent:
          type: string
          enum:
          - low
          - medium
          - high
          nullable: true
        intentDescription:
          type: string
          minLength: 1
          maxLength: 2000
          description: Plain-English firing rule used by the classifier (same semantics as on signals).
        resultCount:
          type: integer
        tookMs:
          type: integer
          nullable: true
        errorCode:
          type: string
          nullable: true
          description: Set on partial failure (e.g. LINKEDIN_RATE_LIMITED). Search row is still persisted.
        errorMessage:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
    LinkedInSearchResult:
      type: object
      properties:
        postUrl:
          type: string
        postExcerpt:
          type: string
        postedAt:
          type: string
          format: date-time
          nullable: true
        author:
          type: object
          properties:
            name:
              type: string
            profileUrl:
              type: string
            headline:
              type: string
              nullable: true
            role:
              type: string
              nullable: true
            company:
              type: string
              nullable: true
        classification:
          type: object
          properties:
            engage:
              type: boolean
            intent:
              type: string
              enum:
              - low
              - medium
              - high
            reason:
              type: string
        triageScore:
          type: integer
          minimum: 0
          maximum: 100
          nullable: true
        rank:
          type: integer
          description: Original position in LinkedIn's ranked result list (0 = top).
  securitySchemes:
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Any of `sa_`, `tk_`, `wk_`, `ak_`, or `mam_` keys. Scope is enforced

        per-endpoint — see individual operation descriptions.

        '