---
title: "Sign a JWT with a key stored in a saved secret without revealing the key."
method: POST
path: "/v1/secrets/jwt"
tags: ["secrets"]
---

# Sign a JWT with a key stored in a saved secret without revealing the key.

`POST /v1/secrets/jwt`

## Request

- Base URL: `https://api.kody.codes`
- URL: `https://api.kody.codes/v1/secrets/jwt`
- Auth: HTTP bearer

Sign a JWT with a key stored in a saved secret without revealing the key. HMAC algorithms (HS256, HS384, HS512) use key material from the secret; RS*, PS*, ES*, and EdDSA use a PKCS#8 PEM private key. This generic primitive only signs caller-provided header and claims; package or execute code should perform any OAuth token exchange separately.

Org permission: `secret:use`.

## Request body

- object
  - `private_key_secret_name` string, required: Saved signing-key secret name, or an opaque {{secret:…}} ref from packageSecrets.get. PKCS#8 PEM for RS*, PS*, ES*, and EdDSA, or HMAC key material for HS*.
  - `private_key_secret_scope` 'session' | 'package' | 'user': Optional secret scope. When omitted, Kody checks accessible scopes in precedence order.
  - `private_key_json_field` string: Optional JSON object field containing the signing key, for example "private_key" for service-account JSON.
  - `algorithm` 'RS256' | 'RS384' | 'RS512' | 'PS256' | 'PS384' | 'PS512' | 'ES256' | 'ES384' | 'ES512' | 'EdDSA' | 'HS256' | 'HS384' | 'HS512'
  - `key_encoding` 'base64' | 'utf8' | 'base64url': HMAC key encoding when algorithm is HS256, HS384, or HS512. Defaults to base64 (DoorDash Drive signing_secret). Not valid for RS*, PS*, ES*, or EdDSA.
  - `header` object: Optional JWT header fields. "alg" must match the requested algorithm when provided.
  - `claims` object, required: JWT claims to sign.

## Response `200`

Success.

- object
  - `jwt` string, required
  - `algorithm` 'RS256' | 'RS384' | 'RS512' | 'PS256' | 'PS384' | 'PS512' | 'ES256' | 'ES384' | 'ES512' | 'EdDSA' | 'HS256' | 'HS384' | 'HS512', required

## Other responses

- `400`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `401`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `403`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `404`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `409`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `413`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `429`: Too many requests (edge IP/token limit) or an entitlement / plan-cap limit. Wait at least `Retry-After` seconds before retrying.
- `500`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `503`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `default`: Error envelope `{ "error": { "code", "message", "details"? } }`.

---

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