---
title: Secrets
path: reference/secrets
status: published
---

# Secrets Reference

Endpoint reference for secrets. For the guide, see [Managing Secrets](../api-guides/secrets). For the model, see [Secrets](../core-concepts/secrets).

**Base path:** `/v1/secrets/`

Partner-scoped variants: `/v1/partner/secrets/*`. Explicit-tenant: `/v1/t/{tenant_id}/secrets/*`. Same request/response shapes.

## GET /v1/secrets/{path}

Read current or specific version.

Query:

| Name | Type | Description |
|------|------|-------------|
| `version` | integer | Specific version (default: current) |

Response `200 OK`:

```json
{
  "path": "environments/production/salesforce/api-credentials",
  "secret_type": "json",
  "version": 3,
  "data": { "...": "..." },
  "metadata": {
    "description": "...",
    "tags": ["salesforce"],
    "owner": "team:integrations"
  },
  "created_at": "2026-01-15T10:30:00Z",
  "updated_at": "2026-04-20T14:22:00Z",
  "expires_at": null,
  "version_count": 3,
  "rotation_policy_id": "rot_quarterly"
}
```

Errors: `404 secret_not_found`, `404 version_not_found`, `410 secret_expired`, `403 access_denied`.

**Scope:** `secrets:read`.

## PUT /v1/secrets/{path}

Create or update (new version).

Body:

| Field | Type | Required |
|-------|------|----------|
| `data` | object | Yes |
| `secret_type` | string | No |
| `metadata.description` | string | No |
| `metadata.tags` | array | No |
| `metadata.owner` | string | No |
| `options.max_versions` | integer 1–100 | No |
| `options.expires_in` | duration | No |
| `options.expires_at` | ISO 8601 | No |
| `options.rotation_policy_id` | string | No |
| `options.secret_policy_id` | string | No |

Response `201 Created` (new) or `200 OK` (update). Returns metadata only; no echo of the plaintext.

**Scope:** `secrets:write`.

## PATCH /v1/secrets/{path}

Update metadata without creating a new version.

Body: `metadata` and/or `options` fields.

**Scope:** `secrets:write`.

## DELETE /v1/secrets/{path}

Soft delete by default, hard delete with `?permanent=true`, version-specific with `?version=N`.

Query:

| Name | Type | Description |
|------|------|-------------|
| `permanent` | boolean | Hard delete (requires `admin`) |
| `version` | integer | Delete this version only |

Response `200 OK` includes `deleted_at` and `recoverable_until` (soft-delete only).

**Scope:** `secrets:delete`.

## POST /v1/secrets/{path}/restore

Restore a soft-deleted secret. Must be within the retention window.

**Scope:** `secrets:write` + `secrets:delete`.

## GET /v1/secrets

List with filters.

Query:

| Name | Type | Description |
|------|------|-------------|
| `prefix` | string | Path prefix |
| `tag` | string (repeatable) | Tag filter |
| `secret_type` | string | Type filter |
| `expires_before` | ISO 8601 | Expiring filter |
| `updated_after` | ISO 8601 | Updated filter |
| `include_expired` | boolean | Default false |
| `include_metadata` | boolean | Full metadata |
| `limit` | integer 1–200 | Default 50 |
| `cursor` | string | Pagination |

Response `200 OK`:

```json
{
  "secrets": [{"path": "...", "version": 3, "...": "..."}],
  "cursor": "eyJp...",
  "has_more": true,
  "total_count": 127
}
```

**Scope:** `secrets:list`.

## GET /v1/secrets/metadata/{path}

Metadata only (no value). Access counts, last-accessed, rotation status.

**Scope:** `secrets:list`.

## GET /v1/secrets/{path}/versions

List all versions.

Query: `limit`, `cursor`, `include_deleted`.

Response `200 OK`:

```json
{
  "path": "...",
  "versions": [
    {"version": 3, "created_at": "...", "is_current": true, "created_by": "..."},
    {"version": 2, "created_at": "...", "is_current": false}
  ],
  "has_more": false
}
```

**Scope:** `secrets:read`.

## GET /v1/secrets/{path}/versions/{version}

Read a specific version explicitly.

**Scope:** `secrets:read`.

## POST /v1/secrets/{path}/rotate

Trigger immediate rotation.

Body:

| Field | Description |
|-------|-------------|
| `reason` | Audit reason |
| `new_value` | Required if the secret has no `auto_generate: true` rotation policy |
| `grace_period` | Override default |
| `notify` | Trigger webhooks (default true) |

**Scope:** `secrets:rotate`.

## GET /v1/secrets/expiring

Secrets expiring within a window.

Query:

| Name | Type | Description |
|------|------|-------------|
| `days` | integer | Default 30 |
| `prefix` | string | Path prefix |

Response:

```json
{
  "secrets": [
    {"path": "test/oauth-token", "expires_at": "...", "days_remaining": 9}
  ]
}
```

**Scope:** `secrets:list`.

## POST /v1/secrets/batch

Batch read. Up to 100 paths per request. See [Batch Operations](../api-guides/batch-operations).

## POST /v1/secrets/batch/metadata

Batch metadata read. Supports wildcard expansion.

## Related

- [Managing Secrets](../api-guides/secrets)
- [Secrets (Concepts)](../core-concepts/secrets)
- [Error Codes](./error-codes)
