Skip to main content
Glama

Onsa

Fetch search results

fetch_leads
Read-onlyIdempotent

Returns the status and any results of a find_leads or continue_campaign job, by jobId. Status values are "pending", "completed" and "stalled", and leads can hold a partial list while "pending". For a find_leads job: "pending" while it has no leads, the agent has not answered and it is under about 15 minutes old, and also while it has leads, until a reply carrying leads completes it; "completed" once the agent posts a reply carrying leads while this is the oldest open job on its campaign, usually its final report (total can still change afterwards); "stalled" as soon as the agent answers without any leads (a question, or none found), or when no lead has arrived after about 15 minutes - derived on each read, so a lead that lands later turns it back to "pending". For a continue_campaign job: "pending" while newLeads is 0 and it is under about 15 minutes old, even after the agent has replied (if that reply confirms a settings-only change, the request is done), and while newLeads is above 0, until a reply carrying leads completes it; "completed" once a reply carrying leads arrives on the campaign while this is the oldest open job there (possibly a late reply from an earlier search), or after about 15 minutes with newLeads 0 when an agent reply was confirmed; "stalled" after about 15 minutes with newLeads 0 when no agent reply was confirmed (agentMessage can still hold one). A reply carrying leads completes only the oldest open job on a campaign, so a newer job stays "pending" meanwhile, even with newLeads above 0. A pending search keeps running when the conversation ends, and a later call with the same jobId returns what it found. First leads arrive within 5 minutes in half of searches and within 9 minutes in 9 of 10. More can arrive until the final report, typically about 10 minutes after the start (9 of 10 within 15). Also returns total (for a find_leads job, the leads the campaign holds now, skipped and deleted ones excluded; for a continuation, equal to newLeads), newLeads (continuations only: leads added to the campaign since the continuation started - a count by time, which can include a late batch from an earlier search), returned (how many this response carries), campaignId (accepted by get_campaign, get_campaign_leads and get_campaign_stats) and campaignUrl, a deep link to the prospects tab for this search in Onsa. agentMessage is the latest agent text in this campaign's chat. For a continuation it is filtered to what was said after the continuation started, though it can be a late message from an earlier search; for a find_leads job it is not filtered, so after a later continue_campaign on the same campaign it can be that request’s reply. A null agentMessage does not mean the agent is silent: artifact-only messages carry no text, and an agent that errored writes nothing there at all. The agent cannot be replied to through this API. While a search is running, one call can wait up to 35 seconds for its first leads or its next batch before answering, so a call can take that long; other calls answer at once. progress carries startedAt, elapsedSeconds and a note on where the search stands, whether the next call will wait, and when results are likely. Each lead carries name, companyName, linkedInUrl, position, headline, location, industry, companyUrl, email (often null), and score (1-5) with scoreExplanation, the reasoning for why this person matches the ICP. A lead has signal (status verified, inferred or none, plus a one-sentence summary) only when the search asked for a need signal. refinements appears when leads are returned and the campaign does not filter by company size; each entry is a suggestion the user can accept, not something already done.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
jobIdYesThe jobId returned by find_leads
limitNoHow many leads to return (default 100)

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
jobIdYes
leadsYes
totalYes
statusYesOne of "pending", "completed", "stalled"; more values may be added later. `leads` can hold a partial list while "pending". For a find_leads job: "pending" while it has no leads, the agent has not answered and it is under about 15 minutes old, and also while it has leads, until a reply carrying leads completes it; "completed" once the agent posts a reply carrying leads while this is the oldest open job on its campaign, usually its final report (`total` can still change afterwards); "stalled" as soon as the agent answers without any leads (a question, or none found), or when no lead has arrived after about 15 minutes - derived on each read, so a lead that lands later turns it back to "pending". For a continue_campaign job: "pending" while `newLeads` is 0 and it is under about 15 minutes old, even after the agent has replied (if that reply confirms a settings-only change, the request is done), and while `newLeads` is above 0, until a reply carrying leads completes it; "completed" once a reply carrying leads arrives on the campaign while this is the oldest open job there (possibly a late reply from an earlier search), or after about 15 minutes with `newLeads` 0 when an agent reply was confirmed; "stalled" after about 15 minutes with `newLeads` 0 when no agent reply was confirmed (agentMessage can still hold one). A reply carrying leads completes only the oldest open job on a campaign, so a newer job stays "pending" meanwhile, even with `newLeads` above 0.
newLeadsYes
progressYes
returnedYes
campaignIdYes
campaignUrlYes
refinementsNo
agentMessageYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedOutput schema / properties / leads / items / properties / signal
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {
      +    "sourceUrl": {
      +      "type": "string"
      +    },
      +    "status": {
      +      "enum": [
      +        "verified",
      +        "inferred",
      +        "none"
      +      ],
      +      "type": "string"
      +    },
      +    "summary": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "status",
      +    "summary"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / refinements
      Added value: +{
      +  "items": {
      +    "additionalProperties": {},
      +    "properties": {
      +      "arguments": {
      +        "additionalProperties": {},
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "kind": {
      +        "type": "string"
      +      },
      +      "offer": {
      +        "type": "string"
      +      },
      +      "reason": {
      +        "type": "string"
      +      },
      +      "tool": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "kind",
      +      "reason",
      +      "offer",
      +      "tool",
      +      "arguments"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  2. Changed2 schema fields changed
    • changedInput schema / properties / jobId / description
      Previous value: -"The jobId returned by find_leads — never invent one"New value: +"The jobId returned by find_leads"
    • changedOutput schema / properties / status / description
      Previous value: -"One of: \"pending\" (search still running), \"completed\" (a batch of leads arrived — not a promise that no more will), \"stalled\" (no leads after ~15 minutes; read agentMessage for the reason and stop polling). Treat an unrecognised value as pending."New value: +"One of \"pending\", \"completed\", \"stalled\"; more values may be added later. `leads` can hold a partial list while \"pending\". For a find_leads job: \"pending\" while it has no leads, the agent has not answered and it is under about 15 minutes old, and also while it has leads, until a reply carrying leads completes it; \"completed\" once the agent posts a reply carrying leads while this is the oldest open job on its campaign, usually its final report (`total` can still change afterwards); \"stalled\" as soon as the agent answers without any leads (a question, or none found), or when no lead has arrived after about 15 minutes - derived on each read, so a lead that lands later turns it back to \"pending\". For a continue_campaign job: \"pending\" while `newLeads` is 0 and it is under about 15 minutes old, even after the agent has replied (if that reply confirms a settings-only change, the request is done), and while `newLeads` is above 0, until a reply carrying leads completes it; \"completed\" once a reply carrying leads arrives on the campaign while this is the oldest open job there (possibly a late reply from an earlier search), or after about 15 minutes with `newLeads` 0 when an agent reply was confirmed; \"stalled\" after about 15 minutes with `newLeads` 0 when no agent reply was confirmed (agentMessage can still hold one). A reply carrying leads completes only the oldest open job on a campaign, so a newer job stays \"pending\" meanwhile, even with `newLeads` above 0."
  3. Changed2 schema fields changed
    • addedOutput schema / properties / progress
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {
      +    "elapsedSeconds": {
      +      "anyOf": [
      +        {
      +          "maximum": 9007199254740991,
      +          "minimum": -9007199254740991,
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "note": {
      +      "type": "string"
      +    },
      +    "startedAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    }
      +  },
      +  "required": [
      +    "startedAt",
      +    "elapsedSeconds",
      +    "note"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "jobId",
      -  "status",
      -  "total",
      -  "returned",
      -  "newLeads",
      -  "campaignId",
      -  "campaignUrl",
      -  "agentMessage",
      -  "leads"
      -]New value: +[
      +  "jobId",
      +  "status",
      +  "total",
      +  "returned",
      +  "newLeads",
      +  "campaignId",
      +  "campaignUrl",
      +  "agentMessage",
      +  "progress",
      +  "leads"
      +]
  4. Changed2 schema fields changed
    • addedOutput schema / properties / status / description
      Added value: +"One of: \"pending\" (search still running), \"completed\" (a batch of leads arrived — not a promise that no more will), \"stalled\" (no leads after ~15 minutes; read agentMessage for the reason and stop polling). Treat an unrecognised value as pending."
    • removedOutput schema / properties / status / enum
      Removed value: -[
      -  "pending",
      -  "completed"
      -]
  5. First observed

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (readOnly, idempotent, non-destructive), and the description adds far more: status state machine for both job types, the 35-second long-poll wait, partial results while pending, timing distributions, null agentMessage semantics, and derived-on-read status behavior. This is exceptional disclosure beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose then status semantics, and nearly every sentence carries load-bearing behavioral detail given the complexity. It is a single dense wall of text with no structure or bullets, which hurts scannability, but little of the content is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a polling tool with an output schema and safety annotations, the description covers everything an agent needs: status meanings, wait behavior, return field semantics, and edge cases like artifact-only messages and late replies. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents jobId and limit, so the baseline is 3. The description does add jobId lifecycle meaning (same jobId returns later-found results) but says nothing about `limit`, so it does not meaningfully exceed the schema for parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope: 'Returns the status and any results of a find_leads or continue_campaign job, by jobId.' It names the two job-producing siblings it serves, so an agent can distinguish it from find_leads/continue_campaign without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly implies polling usage ('a later call with the same jobId returns what it found') and explains the full status lifecycle for both job types. It does not explicitly frame a when-to-use/when-not comparison against siblings beyond naming them, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources