# Add a skill revision

**PUT** `/v1/skills/{skill_id}`

Uploads a new zip bundle as a new revision of an existing skill. Pass the
revision you expect to replace as the required `expected_revision`; the
request fails with `409` if the skill has already moved past it, so the
update cannot race a concurrent write. Name and description are re-read
from the new bundle.

Base URL: `https://api.perplexity.ai`

Tags: `Skills`

## Authorization

| Option | Scheme | Type | Sent as | Scopes |
| --- | --- | --- | --- | --- |
| Option 1 | `HTTPBearer` | `http` | `Authorization: Bearer <token>` | — |

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `skill_id` | `string` | Yes | Skill identifier returned by create or `GET /v1/skills` |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `expected_revision` | `string` | Yes | Opaque revision token the skill must currently be at. The write applies only if it matches, so it cannot race a concurrent update. |

## Request body

Required. Media type: `multipart/form-data`

The skill bundle as a zip archive

### Example request body

```json
{
  "file": "binary"
}
```

## Responses

| Status | Description | Media type |
| --- | --- | --- |
| `200` | The updated skill | `application/json` |
| `400` | Invalid request or bundle | `application/json` |
| `404` | Skill not found | `application/json` |
| `409` | Revision conflict; the skill moved past expected_revision | `application/json` |
| `413` | Bundle exceeds the size limit | `application/json` |
| `429` | Rate limit or upload concurrency limit exceeded | `application/json` |
| `502` | Skill service unavailable | `application/json` |

### Example response: 200 — The updated skill

```json
{
  "created_at": "2026-06-09T00:00:00Z",
  "description": "string",
  "latest_revision": "string",
  "name": "string",
  "revision": "string",
  "skill_id": "string",
  "updated_at": "2026-06-09T00:00:00Z"
}
```

### Example response: 400 — Invalid request or bundle

```json
{
  "error": {
    "code": 0,
    "message": "string",
    "param": "string",
    "type": "string"
  }
}
```

### Example response: 404 — Skill not found

```json
{
  "error": {
    "code": 0,
    "message": "string",
    "param": "string",
    "type": "string"
  }
}
```

### Example response: 409 — Revision conflict; the skill moved past expected_revision

```json
{
  "error": {
    "code": 0,
    "message": "string",
    "param": "string",
    "type": "string"
  }
}
```

### Example response: 413 — Bundle exceeds the size limit

```json
{
  "error": {
    "code": 0,
    "message": "string",
    "param": "string",
    "type": "string"
  }
}
```

### Example response: 429 — Rate limit or upload concurrency limit exceeded

```json
{
  "error": {
    "code": 0,
    "message": "string",
    "param": "string",
    "type": "string"
  }
}
```

### Example response: 502 — Skill service unavailable

```json
{
  "error": {
    "code": 0,
    "message": "string",
    "param": "string",
    "type": "string"
  }
}
```

## Related pages

- [Cancel Agent Response](./cancelagentresponse.md)
- [Create a skill](./createskill.md)
- [Create Agent Response](./createagent.md)
- [Create Async Chat Completion](./create_async_chat_completions_async_chat_completions_post.md)
- [Create Chat Completion](./chat_completions_chat_completions_post.md)
- [Create Contextualized Embeddings](./contextualized_embeddings_v1_contextualizedembeddings_post.md)
- [Create Embeddings](./embeddings_v1_embeddings_post.md)
- [Delete a skill](./deleteskill.md)
- [Download Agent Response File](./downloadagentfile.md)
- [Get a skill](./getskill.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
