> ## 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.

# Bulk create Signals

> One template × up to 1,000 targets → a fleet of Signals in one call.

**Cost: Free to create · each Signal's checks bill per the standard [pay-per-check rules](/concepts/signals#billing-pay-per-check)**

The fleet primitive: watch your whole book of business without 1,000 API calls. Every created Signal shares the template's schedule, criteria, notify and tags — manage them collectively by tag afterwards.

<ParamField body="template" type="object" required>
  <Expandable title="Template fields">
    <ParamField body="name_prefix" type="string">Each Signal is named `{name_prefix} — {target url}`.</ParamField>
    <ParamField body="tags" type="string[]">Applied to every created Signal — your bulk-management handle.</ParamField>
    <ParamField body="schedule" type="object" required>Same shape as [create](/api-reference/signals/create).</ParamField>
    <ParamField body="criteria" type="object" required>Same shape as [create](/api-reference/signals/create).</ParamField>
    <ParamField body="notify" type="object">Omit to use the account [default webhook](/api-reference/account/update) — the usual pattern for fleets.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="targets" type="object[]" required>
  Up to **1,000** entries: `{ "type": "profile", "linkedin_url": "…" }` each.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Retried submissions with the same key return the original result instead of duplicating the fleet.
</ParamField>

### Response

<ResponseField name="data.created" type="integer">Signals created.</ResponseField>
<ResponseField name="data.rejected" type="object[]">Invalid targets with reasons — the rest of the batch still succeeds.</ResponseField>
<ResponseField name="data.estimated_monthly_credits" type="integer">Combined burn for the whole fleet.</ResponseField>
<ResponseField name="data.signals" type="object[]">The created Signal objects.</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.up2data.ai/v1/signals/bulk \
    -H "X-API-Key: $UP2DATA_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: champions-import-2026-07" \
    -d '{
      "template": {
        "name_prefix": "Job change",
        "tags": ["champions", "q3-pipeline"],
        "schedule": { "interval": "1d" },
        "criteria": { "mode": "field_change", "fields": ["headline", "position", "company"] }
      },
      "targets": [
        { "type": "profile", "linkedin_url": "https://linkedin.com/in/a" },
        { "type": "profile", "linkedin_url": "https://linkedin.com/in/b" }
      ]
    }'
  ```

  ```python Python theme={null}
  resp = requests.post(
      "https://api.up2data.ai/v1/signals/bulk",
      headers={"X-API-Key": UP2DATA_API_KEY, "Idempotency-Key": "champions-import-2026-07"},
      json={
          "template": {
              "name_prefix": "Job change",
              "tags": ["champions"],
              "schedule": {"interval": "1d"},
              "criteria": {"mode": "field_change", "fields": ["headline", "position", "company"]},
          },
          "targets": [{"type": "profile", "linkedin_url": u} for u in urls],
      },
  )
  print(resp.json()["data"]["estimated_monthly_credits"])
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "data": {
      "created": 998,
      "rejected": [
        { "linkedin_url": "https://linkedin.com/in/bad-url", "reason": "invalid_url" },
        { "linkedin_url": "https://linkedin.com/in/dupe", "reason": "duplicate_target" }
      ],
      "estimated_monthly_credits": 29940,
      "signals": [
        { "id": "sig_a1", "name": "Job change — linkedin.com/in/a", "tags": ["champions", "q3-pipeline"], "status": "active" }
      ]
    },
    "meta": { "creditsUsed": 0, "billed": false, "reason": "bulk_created", "requestId": "req_bk20amx1" }
  }
  ```
</ResponseExample>

<Tip>
  Prefer one Signal with a `profile_list` target when you want **one webhook stream and one estimate** for the whole list; prefer bulk-created individual Signals when you need **per-person pause/delete and per-person spend attribution**. Same check pricing either way.
</Tip>
