---
title: "Rotate a project credential (owner-only)"
method: POST
path: "/projects/v1/{project_id}/credentials/{credential_id}/rotate"
tags: ["Projects"]
---

# Rotate a project credential (owner-only)

`POST /projects/v1/{project_id}/credentials/{credential_id}/rotate`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/projects/v1/{project_id}/credentials/{credential_id}/rotate`
- Auth: one of:
  - API key in header `SIGN-IN-WITH-X`
  - HTTP bearer

Mints a replacement credential and revokes the old one in a single transaction, reusing the same name. The replacement records `replacement_of`. The new secret is returned exactly once.

## Path parameters

- `project_id` string, required
- `credential_id` string, required

## Headers

- `SIGN-IN-WITH-X` string, required

## Response `201`

Rotated. Carries the new secret ONCE.

- object
  - `credential_id` string
  - `project_id` string
  - `kind` 'anon' | 'service'
  - `name` string
  - `created_at` string, date-time
  - `last_used_at` string, date-time, nullable
  - `expires_at` string, date-time, nullable
  - `revoked_at` string, date-time, nullable
  - `revoked_reason` string, nullable
  - `replacement_of` string, nullable
  - `secret` string: The credential secret, returned EXACTLY ONCE and never recoverable afterwards. Store it immediately. Responses carrying it are sent with `Cache-Control: no-store` and must not be persisted to any client-side result cache.
  - `next_actions` object[]

## Other responses

- `403`: Not an owner of the project's org, or step-up required
- `404`: No such live credential on this project (CREDENTIAL_NOT_FOUND)

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
