---
title: "Store an upstream API credential — add a secret to the vault for broker injection"
method: POST
path: "/credentials"
tags: ["credentials"]
---

# Store an upstream API credential — add a secret to the vault for broker injection

`POST /credentials`

Store an encrypted credential in the vault for automatic broker injection.

Values are encrypted at rest and **never returned** after creation. Set `api_id` to
bind the credential to an API; the broker will inject it automatically when proxying
calls to that API.

---

### `auth_type` reference

Set `auth_type` to tell the broker how to inject the credential into upstream requests.
Based on the [Postman auth type taxonomy](https://learning.postman.com/docs/sending-requests/authorization/authorization-types/).

| `auth_type` | Status | Broker injects | `value` | `identity` |
|---|---|---|---|---|
| `bearer` | ✅ implemented | `Authorization: Bearer {value}` | Token, PAT, or OAuth access token | Not used |
| `basic` | ✅ implemented | `Authorization: Basic base64({identity or "token"}:{value})` | Password or PAT | Username (optional — defaults to `"token"` if omitted, works for GitHub PATs) |
| `apiKey` | ✅ implemented | Custom header or query param `= {value}` | API key | For **compound schemes** (e.g. Discourse `Api-Key` + `Api-Username`): set `identity` to the username — one credential covers both headers when the overlay uses canonical `Secret`/`Identity` scheme names |
| `oauth2` | ⚠️ partial | `Authorization: Bearer {value}` — token must be pre-obtained | Access token (Pipedream-managed flows only via `pipedream_oauth`) | Not used |
| `digest` | 🔲 planned | RFC 2617 challenge-response (nonce/HMAC handshake) | Password | Username |
| `jwt` | 🔲 planned | `Authorization: Bearer {signed_jwt}` — auto-generated from signing key | Private key or secret | Key ID (`kid`) — signing algorithm and claims go in `context` |
| `aws_sig4` | 🔲 planned | `Authorization: AWS4-HMAC-SHA256 ...` signed headers | AWS Secret Access Key | AWS Access Key ID — region and service go in `context` |
| `oauth1` | 🔲 planned | HMAC-SHA1 signed request (nonce + timestamp) | OAuth secret | OAuth consumer key |
| `hawk` | 🔲 planned | `Authorization: Hawk ...` HMAC request signing | Hawk secret | Hawk key ID |
| `ntlm` | 🔲 not planned | Windows NTLM challenge-response | Password | Username + domain |
| `akamai_edgegrid` | 🔲 not planned | Akamai EdgeGrid signing | Client secret | Client token + access token in `context` |

**Notes:**
- `pipedream_oauth` is a reserved value written by the Pipedream integration — do not set it manually.
- For `oauth2` full flows (auth code, client credentials, PKCE, token refresh) see the roadmap.
- `context` (not yet exposed) will hold auxiliary fields for multi-value schemes (JWT claims, AWS region/service, etc.).

---

### Workflow

1. Call `GET /apis/{api_id}` — check `security_schemes` and `credentials_configured` to find gaps.
2. Post this endpoint with `api_id`, `auth_type`, `value` (and `identity` if needed).
3. The broker injects the credential automatically on every proxied call to that API.
4. To scope a credential to a specific toolkit: `POST /toolkits/{id}/credentials`.

If the API has no registered security scheme yet, submit an overlay first: `POST /apis/{api_id}/overlays`.

## Request body

- CredentialCreate
  - `label` string, required
  - `value` string
  - `identity` string, nullable
  - `api_id` string, nullable
  - `server_variables` object, nullable
  - `auth_type` 'bearer' | 'basic' | 'apiKey' | 'none', nullable — How this credential maps to the upstream API's authentication scheme. The broker uses this to find the right security scheme in the spec — it resolves by type, not by the bespoke scheme name in the overlay. | Value | Injects as | When to use | |---|---|---| | `bearer` | `Authorization: Bearer {value}` | REST APIs, OAuth access tokens, JWTs. GitHub REST API, Deepgram, Slack, etc. | | `basic` | `Authorization: Basic base64({identity??'token'}:{value})` | HTTP Basic auth, git-over-HTTPS. Set `identity` to the username; omit for GitHub PATs (any username accepted). | | `apiKey` | Custom header or query param `= {value}` | API key in a named header (X-API-Key, Api-Key, X-Auth-Key, etc.). For **compound** schemes (e.g. Discourse Api-Key + Api-Username) where the overlay uses canonical `Secret`/`Identity` scheme names, set `identity` to the username/account — a single credential covers both headers. | | `none` | *(nothing injected)* | No-auth APIs where the credential exists only to carry `server_variables` for routing. |
  - `scheme` object, nullable — Self-describing injection rule. When set, the broker injects the credential directly from this blob without looking up the API spec or overlay at runtime. Format: {"in": "header", "name": "Authorization", "prefix": "Bearer "} or {"in": "header", "name": "X-Api-Key"}. Supports encode=base64 for Basic auth: {"in": "header", "name": "Authorization", "prefix": "Basic ", "encode": "base64"}. For compound schemes: {"secret": {"in": "header", ...}, "identity": {"in": "header", ...}}.
  - `routes` string[], nullable — Hostnames or host+path patterns this credential should be injected into. Each entry is stored as (host, path_prefix) in credential_routes. Example: ["github.com", "api.github.com"].

## Response `201`

Successful Response

- CredentialOut — Upstream API credential metadata. Secret values are never returned after creation.
  - `id` string, required
  - `label` string, required
  - `identity` string, nullable
  - `api_id` string, nullable
  - `auth_type` string, nullable
  - `server_variables` object, nullable
  - `scheme` object, nullable
  - `routes` string[], nullable
  - `created_at` number, nullable
  - `updated_at` number, nullable
  - `account_id` string, nullable
  - `app_slug` string, nullable
  - `synced_at` number, nullable

## Other responses

- `422` — Validation Error

## Changes

- **2026-04-14** `bd463fcefb14` — 9 info
  - added the new optional request property `routes`
  - added the new optional request property `scheme`
  - added the new optional request property `server_variables`
  - the request property `value` became optional
  - …5 more
- **2026-04-13** `76e8f6063728` — 10 breaking, 6 warning, 24 info
  - added the new required request property `label`
  - added the new required request property `value`
  - removed `#/components/schemas/BearerTokenCreateRequest, #/components/schemas/ApiKeyCreateRequest, #/components/schemas/BasicAuthCreateRequest, #/components/schemas/OAuth2CreateRequest` from the request body `oneOf` list
  - the request's body type/format changed from ``/`` to `object`/``
  - …36 more

[Change history](https://skmtc.dev/jentic/apis/jentic-control-plane-api/changes/credentials/post.md)

---

[API](https://skmtc.dev/jentic/apis/jentic-control-plane-api.md) · [All operations](https://skmtc.dev/jentic/apis/jentic-control-plane-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/jentic/jentic-control-plane-api/revisions/bd463fcefb14/schema)
