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

# Check a Signal now

> Run one real check immediately — same scrape, billing, and Trigger rules as a scheduled check.

**Cost: same as the Signal's underlying scrape · failed scrapes free · does not advance the schedule**

<Card title="How Signals work" icon="satellite-dish" href="/concepts/signals" type="tip" horizontal arrow="true" cta="Read the guide">
  Signals are scheduled change monitoring, billed per check. See what you can watch and how it's priced.
</Card>

Runs the check immediately without changing `next_check_at`. If criteria match (and this is not the baseline), a real Trigger is created and the webhook fires.

`POST /v1/signals/{id}/test` is a backward-compatible alias for this endpoint.

<ParamField path="id" type="string" required />

### Response

Discriminated by `data.status`:

| `status`      | Meaning                                           |
| ------------- | ------------------------------------------------- |
| `matched`     | Criteria matched; Trigger created when applicable |
| `not_matched` | Check succeeded; no Trigger (includes baseline)   |
| `failed`      | Scrape/check failed; not billed                   |
| `paused`      | Signal paused (credits/budget); not billed        |

Also returns `is_baseline`, `criteria_matched`, `diff`, `error_type` / `error_message` on failure, and `webhook` when a delivery was enqueued.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.up2data.ai/v1/signals/sig_9dk2m1xq/check-now \
    -H "X-API-Key: $UP2DATA_API_KEY"
  ```

  ```python Python theme={null}
  resp = requests.post(
      f"https://api.up2data.ai/v1/signals/{signal_id}/check-now",
      headers={"X-API-Key": UP2DATA_API_KEY},
  )
  result = resp.json()["data"]
  print(result["status"], result.get("matched"), result.get("is_baseline"))
  ```

  ```ts TypeScript theme={null}
  const res = await fetch(
    `https://api.up2data.ai/v1/signals/${signalId}/check-now`,
    { method: "POST", headers: { "X-API-Key": apiKey } },
  );
  const { data, meta } = await res.json();
  // meta.reason: baseline_established | check_matched | check_completed | check_failed | …
  ```
</RequestExample>

<ResponseExample>
  ```json 200 — matched theme={null}
  {
    "data": {
      "signal_id": "sig_9dk2m1xq",
      "check_number": 2,
      "status": "matched",
      "matched": true,
      "is_baseline": false,
      "billed": true,
      "credits_used": 1,
      "trigger_id": "trg_abc123",
      "criteria_matched": ["headline"],
      "diff": {
        "headline": { "before": "VP Eng @ Acme", "after": "CTO @ Beta" }
      },
      "webhook": { "status": "retrying", "attempts": 0, "delivery_id": "wh_signal_trg_abc123" }
    },
    "meta": { "creditsUsed": 1, "billed": true, "reason": "check_matched", "requestId": "req_ts5k18dq" }
  }
  ```

  ```json 200 — failed check theme={null}
  {
    "data": {
      "signal_id": "sig_9dk2m1xq",
      "check_number": 1,
      "status": "failed",
      "matched": false,
      "billed": false,
      "credits_used": 0,
      "error_type": "invalid_request",
      "error_message": "could not derive a Harvest searchQuery from the search URL"
    },
    "meta": { "creditsUsed": 0, "billed": false, "reason": "check_failed", "requestId": "req_fail1" }
  }
  ```
</ResponseExample>

<Tip>
  To verify webhook delivery without needing criteria to match, use [`POST /v1/signals/{id}/test-webhook`](/api-reference/signals/test-webhook) — free, no scrape.
</Tip>
