ApiKeys

Regenerate an API key ("same key, new secret")

Issues a replacement credential under the same name and scope, then revokes the original. Returns 201 with the plaintext replacement key exactly once, the same one-time delivery POST /api/v1/api-keys uses.

Order: the replacement is created FIRST, then the original is deleted — the reverse would lose the caller's access entirely if creation failed.

Expiry policy, not remaining time: a key that never expired stays non-expiring; a key that had any expiry gets a fresh 90-day window from now, not the old key's remaining balance.

Non-cascading: unlike DELETE /api/v1/api-keys/{id}, this does NOT revoke keys the original minted. Regenerating is "same key, new secret", not "this credential and everything descended from it is dead": keys the original minted stay alive with a null created_by_key_id.

A key belonging to another project is indistinguishable from a missing one — both return 404.

Requires admin scope, the same tier as the other three /api/v1/api-keys routes: key management is the one capability that lets a compromised credential outlive its own revocation.

Caller caps, when the caller is itself an API key (the key creation rule, extended to key rotation): the replacement's expires_at is capped to the caller key's own expiry (silently — whichever is earlier of the policy-derived value above and the caller's own ceiling, "never" acting as +infinity), and the replacement's scope must not exceed the caller key's own scope — that one is refused outright (403, not silently narrowed) rather than handing back a less powerful key than the target had. A session-authenticated caller (the dashboard) gets neither cap.

The MCP tool regenerate_api_key calls this route. Terraform has no equivalent, deliberately: its model for rotating a key it manages is taint/recreate.

post/api/v1/api-keys/{id}/regenerate

Request

  • Base URL: https://app.lastping.dev
  • URL: https://app.lastping.dev/api/v1/api-keys/{id}/regenerate
  • Auth: API key in header X-Api-Key

Response

Replacement key created. The original has been revoked unless old_key_revoked is false.

idstring uuid required

Unique API key identifier.

namestring required

Human-readable label for the key.

prefixstring required

First 10 characters of the key — a non-secret identifier shown in place of the full value.

created_atstring date-time required

RFC 3339 UTC timestamp when the key was created.

expires_atstring date-time

RFC 3339 UTC expiry timestamp, or omitted for a key that never expires.

last_used_atstring date-time

RFC 3339 UTC timestamp of the most recent request this key authenticated. Omitted if the key has never been used since this field was added — never rendered as a zero/epoch time.

last_used_surface'mcp' | 'terraform' | 'api' | 'ingest'

Which client surface last used this key, omitted if unknown. ingest means the latest use was sending telemetry (traces, metrics or logs); telemetry use is recorded about once a minute per key, so last_used_at can trail the newest export by up to a minute. For mcp, terraform and api the value is best-effort and spoofable: derived from the caller-controlled User-Agent header on the authenticating request, not from any cryptographic or protocol-level signal. Useful for an honest "did my client ever successfully authenticate?" indicator — never use it for authorization or access control.

scope'read' | 'write' | 'admin' | 'ingest' required

What this key is permitted to do. Always present. Unlike last_used_surface above — which is a spoofable hint derived from a caller-supplied header — this is the value the server actually checks. ingest sends telemetry only and cannot call this API.

check_idstring uuid

The one monitor an ingest key is bound to. Omitted for an unbound key and for every key of another scope.

created_by_key_idstring uuid

The API key that minted this one, omitted for a key created from the dashboard (which has no parent key) or whose parent has since been deleted.

Revoking a key revokes every key below it in this chain. A key minted by a key minted by the key you delete goes with it, all at once. A key created from the dashboard is never below anything and is unaffected.

keystring required

The plaintext replacement key. Store it immediately — it cannot be retrieved again.

old_key_revokedboolean required

true when the original key was deleted and no longer works. false when the replacement was created but deleting the original failed: the original still works and is still listed by GET /api/v1/api-keys, so revoke it by id with DELETE /api/v1/api-keys/{id}. The response is 201 either way, because the replacement key works.

Example response

{
  "id": "e1d2c3b4-0000-0000-0000-000000000001",
  "name": "github-actions",
  "prefix": "lp_Wwut111",
  "created_at": "2026-07-01T12:00:00Z",
  "expires_at": "2026-12-31T00:00:00Z",
  "last_used_at": "2026-08-01T09:30:00Z",
  "last_used_surface": "mcp",
  "scope": "write",
  "check_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "created_by_key_id": "e1d2c3b4-0000-0000-0000-000000000002",
  "key": "lp_Nyrz222g_kIqphznbRMh6M20-NvXdWWZ",
  "old_key_revoked": true
}

Changes

No recorded changes to this operation across all 2 revisions of this API.