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

# Run a Template

> Run a template with its inputs and get its rows: Google Maps leads, Amazon products, LinkedIn jobs, Google Trends and more.

A run takes the template's inputs, reads the pages it needs and returns one row per result. Find a template's slug and inputs with [List Templates](https://docs.spidra.io/api-reference/templates/list.md) and [Get a Template](https://docs.spidra.io/api-reference/templates/get.md), or on its page in the dashboard (the **API** tab there shows the exact request).

## Example request

```bash cURL theme={null}
curl -X POST https://api.spidra.io/api/templates/google-maps-leads/runs \
  -H "Authorization: Bearer $SPIDRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": { "query": "dentist", "areas": ["Lekki, Lagos"] }
  }'
```

```javascript JavaScript theme={null}
const res = await fetch("https://api.spidra.io/api/templates/google-maps-leads/runs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SPIDRA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ inputs: { query: "dentist", areas: ["Lekki, Lagos"] } }),
});
const { run } = await res.json();
```

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

res = requests.post(
    "https://api.spidra.io/api/templates/google-maps-leads/runs",
    headers={"Authorization": f"Bearer {os.environ['SPIDRA_API_KEY']}"},
    json={"inputs": {"query": "dentist", "areas": ["Lekki, Lagos"]}},
)
run = res.json()["run"]
```

The run starts and the response is `202` with `status: "running"`:

```json theme={null}
{
  "status": "success",
  "run": {
    "runId": "dfefa844-ad1f-4400-b127-dc17a186d9c2",
    "template": "google-maps-leads",
    "templateVersion": 4,
    "presetId": null,
    "tool": "batch",
    "status": "running",
    "inputs": { "query": "dentist", "areas": ["Lekki, Lagos"], "pages": 1, "findContacts": false, "language": "en" },
    "createdAt": "2026-10-24T18:46:01.000Z",
    "finishedAt": null,
    "creditsUsed": null,
    "urlCount": 1,
    "rowCount": 0,
    "job": { "tool": "batch", "id": "a566e5de-c46a-476c-a095-b26bd5cc38cf" },
    "progress": { "completed": 0, "failed": 0, "total": 1 },
    "failures": []
  }
}
```

`inputs` comes back with the defaults filled in. Poll [GET /template-runs/\{runId}](https://docs.spidra.io/api-reference/templates/get-run.md) every few seconds until `status` isn't `running`.

## Wait for a quick result

Add `"wait": true` and a quick run comes back complete, with its rows, in the same response (`200`). Templates that read up to 10 pages wait up to 45 seconds; search-based templates wait up to 20 seconds. Anything longer answers `202` as above and you poll it as usual. Templates that run several searches (such as rank trackers), and runs with a second step switched on, always answer `202`.

```bash theme={null}
curl -X POST https://api.spidra.io/api/templates/product-hunt-leaderboard/runs \
  -H "Authorization: Bearer $SPIDRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "inputs": { "period": "weekly", "week": "2026-W42" }, "wait": true }'
```

## Statuses

| `status` | Meaning |
| - | - |
| `running` | Still reading pages. |
| `completed` | Every page was read. `rows` holds the results. |
| `partial` | Some pages couldn't be read. They're listed in `failures` and aren't charged; `rows` holds the rest. |
| `failed` | Nothing could be read. `error` says why. A failed run costs nothing. |

## Cost

A run costs what the same job costs with the tool behind it, usually 1 credit per page read. Most templates use no AI. [Estimate a Template Run](https://docs.spidra.io/api-reference/templates/estimate.md) gives the number before you run it, for free. Pages that fail aren't charged, and a run whose site can't be read fails without charging.

## Errors

| Status | When |
| - | - |
| `422` | An input is missing or wrong. `errors` lists each one, for example `{ "field": "areas", "message": "Areas is required." }`. |
| `403` | Not enough credits for the run. |
| `404` | No template with this slug. |
| `429` | More than 20 template runs a minute. |
| `503` | The template is paused for maintenance (`TEMPLATE_PAUSED`). Nothing was charged. |


## OpenAPI

````yaml POST /templates/{slug}/runs
openapi: 3.1.0
info:
  title: Spidra API
  version: 1.0.0
  description: >-
    Public API endpoints for web scraping via Spidra. Authenticate with
    `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.spidra.io/api
security:
  - BearerAuth: []
  - ApiKeyAuth: []
paths:
  /templates/{slug}/runs:
    post:
      tags:
        - Templates
      summary: Run a Template
      description: >-
        Starts a run. Returns `202` with the run while it works; poll [GET
        /template-runs/{runId}](/api-reference/templates/get-run) for its rows.
        With `wait: true`, a quick run comes back complete with its rows
        (`200`): up to 45 seconds for templates that read up to 10 pages, up to
        20 seconds for search-based templates.
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
          description: The template's slug.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                inputs:
                  type: object
                  description: >-
                    The template's inputs, by key. [GET
                    /templates/{slug}](/api-reference/templates/get) lists them.
                wait:
                  type: boolean
                  default: false
                  description: >-
                    Wait for a quick run to finish: up to 45 seconds for
                    templates that read up to 10 pages, 20 seconds for
                    search-based ones. Templates that run several searches, or
                    have a second step on, ignore it.
            example:
              inputs:
                query: dentist
                areas:
                  - Lekki, Lagos
      responses:
        '200':
          description: The run finished within `wait`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  run:
                    $ref: '#/components/schemas/TemplateRun'
        '202':
          description: The run started.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  run:
                    $ref: '#/components/schemas/TemplateRun'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Not enough credits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No template with this slug.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Some inputs need fixing. `errors` lists each field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidInputError'
        '429':
          description: More than 20 template runs a minute.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: The template is paused (`TEMPLATE_PAUSED`). Nothing was charged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    TemplateRun:
      type: object
      properties:
        runId:
          type: string
        template:
          type: string
          description: The template's slug.
        templateVersion:
          type: integer
        presetId:
          type:
            - string
            - 'null'
          description: Set when the run came from a preset.
        tool:
          type: string
        status:
          type: string
          enum:
            - running
            - completed
            - partial
            - failed
            - cancelled
          description: >-
            `partial`: some pages failed (they aren't charged) and the rest came
            back.
        inputs:
          type: object
          description: The inputs the run used, with defaults filled in.
        createdAt:
          type: string
          format: date-time
        finishedAt:
          type:
            - string
            - 'null'
          format: date-time
        creditsUsed:
          type:
            - number
            - 'null'
          description: Null while running.
        urlCount:
          type:
            - integer
            - 'null'
          description: Pages the run reads.
        rowCount:
          type:
            - integer
            - 'null'
        progress:
          type: object
          properties:
            completed:
              type: integer
            failed:
              type: integer
            total:
              type: integer
        rows:
          type: array
          items:
            type: object
            additionalProperties: true
          description: >-
            The results, one object per row, with every field the site returned.
            Present once the run has finished (leave out with `?rows=false`).
        failures:
          type: array
          items:
            type: object
            properties:
              url:
                type: string
              error:
                type: string
          description: Pages that couldn't be read. Not charged.
        error:
          type: string
          description: Why the run failed.
        followStep:
          type: object
          description: >-
            Templates with a second step switched on (such as finding emails and
            social links on each business's website).
          properties:
            status:
              type: string
              enum:
                - waiting
                - running
                - completed
                - failed
            sites:
              type: integer
            pagesLoaded:
              type: integer
            pagesFailed:
              type: integer
            pagesWaiting:
              type: integer
            creditsUsed:
              type: number
            error:
              type: string
        summary:
          type: object
          description: >-
            Rank trackers only: how many keywords or points ranked, and the
            average position.
        job:
          type: object
          properties:
            tool:
              type: string
            id:
              type:
                - string
                - 'null'
          description: The tool job behind the run, for that tool's own endpoints.
    ErrorResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        message:
          type: string
      required:
        - status
        - message
    InvalidInputError:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        code:
          type: string
          enum:
            - INVALID_INPUT
        message:
          type: string
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
          description: One entry per field that needs fixing.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.