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

# Create a batch job

> Async fan-out for up to 1,000 operations — enrich known URLs or batch multiple API calls (searches, enrichments, etc.).

**Cost: each item bills at that operation's normal credit rate · submission free · pay only on success, per item**

One async primitive for volume work. Submit up to **1,000 items** per job:

* **Enrich** known URLs: `{ "type": "profile", "url": "…" }` (also `company`, `post`)
* **Batch any supported operation**: `{ "operation": "search.people", "body": { "filters": {…}, "max_results": 500 } }`

Mix enrichment and search operations in one job — e.g. three different people searches plus a company enrich. Results arrive via `batch.completed` [webhook](/concepts/webhooks) and/or [polling the job](/api-reference/batch/get). Full walkthrough in the [Bulk enrichment guide](/guides/bulk-enrichment).

<ParamField body="items" type="object[]" required>
  Up to **1,000** entries. Each item is either an enrich target or a batchable operation.

  <Expandable title="Enrich item">
    `{ "type": "profile" | "company" | "post", "url": "…" }`
  </Expandable>

  <Expandable title="Operation item">
    `{ "operation": "search.people" | "search.companies" | "search.people.sales_nav" | "search.companies.sales_nav" | "search.jobs" | "search.posts" | "profiles.enrich" | "companies.enrich" | "posts.enrich", "body": {…} }`
  </Expandable>
</ParamField>

<ParamField body="webhook_url" type="string">
  HTTPS endpoint for the `batch.completed` event. Omit to use polling only.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Retried submissions with the same key return the original job instead of creating a duplicate.
</ParamField>

### Response

<ResponseField name="data.job_id" type="string">Use with [`GET /v1/batch/{job_id}`](/api-reference/batch/get).</ResponseField>
<ResponseField name="data.status" type="string">`processing` on acceptance.</ResponseField>
<ResponseField name="data.total" type="integer">Items accepted into the job.</ResponseField>
<ResponseField name="data.estimated_completion" type="string">ISO 8601 estimate.</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.up2data.ai/v1/batch \
    -H "X-API-Key: $UP2DATA_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: import-chunk-014" \
    -d '{
      "items": [
        { "type": "profile", "url": "https://linkedin.com/in/a" },
        { "type": "profile", "url": "https://linkedin.com/in/b" },
        { "type": "company", "url": "https://linkedin.com/company/acme" }
      ],
      "webhook_url": "https://app.example.com/hooks/up2data"
    }'
  ```

  ```python Python theme={null}
  resp = requests.post(
      "https://api.up2data.ai/v1/batch",
      headers={"X-API-Key": UP2DATA_API_KEY, "Idempotency-Key": "import-chunk-014"},
      json={
          "items": [{"type": "profile", "url": u} for u in urls]
          + [{"type": "company", "url": c} for c in company_urls],
          "webhook_url": HOOK_URL,
      },
  )
  job_id = resp.json()["data"]["job_id"]
  ```

  ```javascript Node theme={null}
  const resp = await fetch("https://api.up2data.ai/v1/batch", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.UP2DATA_API_KEY,
      "Content-Type": "application/json",
      "Idempotency-Key": "import-chunk-014",
    },
    body: JSON.stringify({
      items: urls.map((url) => ({ type: "profile", url })),
      webhook_url: HOOK_URL,
    }),
  });
  const { job_id } = (await resp.json()).data;
  ```

  ```go Go theme={null}
  items := make([]map[string]string, 0, len(urls))
  for _, u := range urls {
  	items = append(items, map[string]string{"type": "profile", "url": u})
  }
  body, _ := json.Marshal(map[string]any{"items": items, "webhook_url": hookURL})
  req, _ := http.NewRequest("POST",
  	"https://api.up2data.ai/v1/batch", bytes.NewReader(body))
  req.Header.Set("X-API-Key", os.Getenv("UP2DATA_API_KEY"))
  req.Header.Set("Idempotency-Key", "import-chunk-014")
  req.Header.Set("Content-Type", "application/json")
  resp, err := http.DefaultClient.Do(req)
  ```
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "data": {
      "job_id": "job_7hd92kfa",
      "status": "processing",
      "total": 3,
      "estimated_completion": "2026-07-07T14:03:00Z"
    },
    "meta": {
      "creditsUsed": 0,
      "creditsRemaining": 98419,
      "billed": false,
      "reason": "job_accepted",
      "requestId": "req_0pl2m8xz"
    }
  }
  ```
</ResponseExample>

**Rate limit:** submission counts as 1 request; items don't count. Concurrent jobs are capped at 5 per org by default — see [Rate limits](/rate-limits).
