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

# Retry Failed Batch Scrapes

> Re-queue only the failed scrapes in a completed batch

After a batch completes with some failures, retry only the failed scrapes. Successful items are never touched. Fresh credits are reserved for the retry, and the batch status resets to `running`.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.spidra.io/api/batch/scrape/YOUR_BATCH_ID/retry \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const res = await fetch(
    `https://api.spidra.io/api/batch/scrape/${batchId}/retry`,
    {
      method: "POST",
      headers: { "x-api-key": "YOUR_API_KEY" },
    }
  );
  const { retriedCount } = await res.json();
  console.log(`${retriedCount} items re-queued`);

  // Poll the same batchId until it completes again
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      f"https://api.spidra.io/api/batch/scrape/{batch_id}/retry",
      headers={"x-api-key": "YOUR_API_KEY"},
  )
  print(f"{resp.json()['retriedCount']} items re-queued")
  ```
</CodeGroup>

***

## Full Retry Pattern

```javascript theme={null}
async function runWithRetry(urls, options, maxAttempts = 3) {
  // Submit the initial batch
  const submit = await fetch("https://api.spidra.io/api/batch/scrape", {
    method: "POST",
    headers: {
      "x-api-key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ urls, ...options }),
  });
  const { batchId } = await submit.json();

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    // Poll until terminal
    let data;
    while (true) {
      const res = await fetch(
        `https://api.spidra.io/api/batch/scrape/${batchId}`,
        { headers: { "x-api-key": "YOUR_API_KEY" } }
      );
      data = await res.json();
      if (["completed", "failed", "cancelled"].includes(data.status)) break;
      await new Promise((r) => setTimeout(r, 3000));
    }

    if (data.failedCount === 0) break; // All done

    if (attempt < maxAttempts) {
      console.log(`Attempt ${attempt}: ${data.failedCount} failed. Retrying...`);
      await fetch(
        `https://api.spidra.io/api/batch/scrape/${batchId}/retry`,
        { method: "POST", headers: { "x-api-key": "YOUR_API_KEY" } }
      );
    }
  }

  // Fetch final state
  const final = await fetch(
    `https://api.spidra.io/api/batch/scrape/${batchId}`,
    { headers: { "x-api-key": "YOUR_API_KEY" } }
  );
  return (await final.json()).items;
}
```

***

## Response

**`202 Accepted`:**

```json theme={null}
{
  "status": "queued",
  "retriedCount": 3
}
```

| Field          | Type       | Description                                |
| -------------- | ---------- | ------------------------------------------ |
| `status`       | `"queued"` | Confirms the retry was accepted            |
| `retriedCount` | `number`   | Number of failed items that were re-queued |

After a successful retry:

* Failed items reset to `pending` status
* Batch `failedCount` decrements by `retriedCount`
* Batch `status` resets to `running`
* Poll the same `batchId` — it will complete again when all retried items finish

***

## Errors

| Code  | Reason                                                                     |
| ----- | -------------------------------------------------------------------------- |
| `400` | No failed items to retry in this batch                                     |
| `401` | Missing `x-api-key` header                                                 |
| `403` | Monthly credit limit reached — not enough credits to reserve for the retry |
| `404` | No batch found with this ID, or it belongs to a different user             |

**No failed items:**

```json theme={null}
{
  "status": "error",
  "message": "No failed items to retry.",
  "code": "NO_FAILED_ITEMS"
}
```

***

<CardGroup cols={2}>
  <Card title="Get Batch Status" icon="magnifying-glass" href="/api-reference/scraping/batch-scrape-status">
    Poll for results after retrying
  </Card>

  <Card title="Cancel a Batch" icon="xmark" href="/api-reference/scraping/batch-scrape-cancel">
    Stop the batch entirely instead
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /batch/scrape/{batchId}/retry
openapi: 3.1.0
info:
  title: Spidra API
  version: 1.0.0
  description: >-
    Public API endpoints for web scraping via Spidra. Authentication is via API
    key passed in the `x-api-key` header.
servers:
  - url: https://api.spidra.io/api
security:
  - ApiKeyAuth: []
paths:
  /batch/scrape/{batchId}/retry:
    post:
      tags:
        - Batch Scraping
      summary: Retry Failed Items
      description: >-
        Re-queue only the failed items in a completed batch. Successful items
        are never touched. Fresh credits are reserved for the retry.
      parameters:
        - name: batchId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The batch ID containing failed items to retry
      responses:
        '202':
          description: Failed items re-queued
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - queued
                  retriedCount:
                    type: integer
                    description: Number of failed items that were re-queued
              example:
                status: queued
                retriedCount: 3
        '400':
          description: No failed items to retry in this batch
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                status: error
                message: No failed items to retry.
                code: NO_FAILED_ITEMS
        '401':
          description: Missing x-api-key header
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Monthly credit limit reached — not enough credits for the retry
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Batch not found or belongs to a different user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        message:
          type: string
      required:
        - status
        - message
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````