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

# GET /api/skills — List All Skills in Your Workspace

> Retrieve a paginated list of every published Skill scoped to your current Workspace, including IDs, names, versions, and timestamps.

`GET /api/skills` returns every Skill that exists in your current Workspace. Use this endpoint to build dashboards, sync Skills to external tools, or discover `skill_id` values before calling [`POST /v1/skills/run`](/api-reference/skills/run). Results are returned newest-first and can be paginated with `page` and `page_size` query parameters.

## Endpoint

```text theme={null}
GET https://api.valendata.com/api/skills
```

## Authentication

This endpoint requires a session token, not an API key. Pass your JWT in the `Authorization` header:

```http theme={null}
Authorization: Bearer YOUR_SESSION_TOKEN
```

<Note>
  To get a session token, call `POST /api/auth/login` with your email and password. The response includes a `token` field, use that here.
</Note>

## Query Parameters

<ParamField query="page" default="1" type="integer">
  One-based page number to return. Combine with `page_size` to page through large Skill libraries.
</ParamField>

<ParamField query="page_size" default="20" type="integer">
  Number of Skill objects per page. Accepts values between `1` and `100`.
</ParamField>

## Example Request

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl https://api.valendata.com/api/skills \
      -H "Authorization: Bearer YOUR_SESSION_TOKEN"
    ```
  </Tab>

  <Tab title="cURL (paginated)">
    ```bash theme={null}
    curl "https://api.valendata.com/api/skills?page=2&page_size=10" \
      -H "Authorization: Bearer YOUR_SESSION_TOKEN"
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    response = requests.get(
        "https://api.valendata.com/api/skills",
        headers={"Authorization": "Bearer YOUR_SESSION_TOKEN"},
        params={"page": 1, "page_size": 20},
    )

    skills = response.json()["skills"]
    for skill in skills:
        print(skill["id"], skill["name"])
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    const response = await fetch(
      "https://api.valendata.com/api/skills?page=1&page_size=20",
      {
        headers: { "Authorization": "Bearer YOUR_SESSION_TOKEN" },
      }
    );

    const { skills, total } = await response.json();
    console.log(`Fetched ${skills.length} of ${total} skills`);
    ```
  </Tab>
</Tabs>

## Response

A successful request returns HTTP `200` with a JSON envelope containing a paginated list of Skill objects.

### Envelope Fields

<ResponseField name="skills" type="array">
  Array of Skill objects for the current page. See [Skill Object](#skill-object) below for the shape of each element.
</ResponseField>

<ResponseField name="total" type="integer">
  The total number of Skills in your Workspace, regardless of pagination. Use this to calculate how many pages remain: `Math.ceil(total / page_size)`.
</ResponseField>

<ResponseField name="page" type="integer">
  The page number that was applied to this response, reflecting the `page` parameter you sent (or the default of `1`).
</ResponseField>

<ResponseField name="page_size" type="integer">
  The page size that was applied to this response, reflecting the `page_size` parameter you sent (or the default of `20`).
</ResponseField>

### Skill Object

<ResponseField name="id" type="string">
  Unique identifier for the Skill, formatted as `skl_...`. Pass this value as `skill_id` when calling [`POST /v1/skills/run`](/api-reference/skills/run).
</ResponseField>

<ResponseField name="name" type="string">
  The human-readable name of the Skill as set when it was created or last updated in the dashboard.
</ResponseField>

<ResponseField name="description" type="string">
  A short description of what the Skill does, drawn from the task prompt or manually entered by the author.
</ResponseField>

<ResponseField name="version" type="string">
  The currently published version of the Skill. Valendata versions Skills on every publish so older integrations continue working even after you update the automation logic.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 UTC timestamp indicating when the Skill was first created.
</ResponseField>

### Example Response

```json theme={null}
{
  "skills": [
    {
      "id": "skl_b281b8165a23",
      "name": "Google Maps SF Software Companies Scraper",
      "description": "Scrapes software companies in San Francisco from Google Maps, including name, website, address, rating, and reviews.",
      "version": "1.0.0",
      "created_at": "2026-08-01T14:22:11Z"
    },
    {
      "id": "skl_c394d9276b34",
      "name": "Competitor Pricing Monitor",
      "description": "Extracts product names, prices, and stock status from a target e-commerce URL.",
      "version": "1.2.3",
      "created_at": "2026-07-28T09:45:00Z"
    }
  ],
  "total": 2,
  "page": 1,
  "page_size": 20
}
```

## Paginating Through All Skills

If your Workspace contains more Skills than a single page can hold, iterate over `page` until you have retrieved all records.

```python theme={null}
import requests

all_skills = []
page = 1
page_size = 100

while True:
    response = requests.get(
        "https://api.valendata.com/api/skills",
        headers={"Authorization": "Bearer YOUR_SESSION_TOKEN"},
        params={"page": page, "page_size": page_size},
    )
    payload = response.json()
    all_skills.extend(payload["skills"])

    if page * page_size >= payload["total"]:
        break
    page += 1

print(f"Retrieved {len(all_skills)} skills in total")
```

## Error Handling

| HTTP Status | Meaning                                                                                           |
| ----------- | ------------------------------------------------------------------------------------------------- |
| `401`       | Unauthorized, session token is missing or expired.                                                |
| `429`       | Rate limited, slow down your request cadence.                                                     |
| `500`       | Internal error, check [status.valendata.com](https://status.valendata.com) for ongoing incidents. |
