Integrations
Secret setup URL reference
Official Kody doc
Use the hosted /account/secrets/new page whenever the user needs to enter
a secret value such as an API key or personal access token. Secrets stay on the
setup page; send the URL and wait until they confirm save.
If the secret will power a downstream package or package app, open
search({ entity: "guide:integration_bootstrap" }) before building that
package. For the common non-OAuth path after bootstrap, open
search({ entity: "guide:secret_backed_integration" }). This guide covers the
secret-collection step only.
When to use /account/secrets/new
Use it when:
- the user must provide a sensitive value
- a named secret needed for
fetchplaceholders or a named lookup (for examplesecretJwtSign) is missing - the user needs to rotate a stored secret value
Send the /account/secrets/new URL and have them paste into Secret value on
that page.
URL format
Provide the user a URL like:
https://<your-kody-origin>/account/secrets/new?name=exampleApiKey&description=Example%20API%20key&expiresAt=2026-12-01T00:00:00.000Z&allowedHosts=api.example.com&scope=user&allowedPackages=pkg_123
When name is present, the page focuses and scrolls to the secret value input
so the user can paste immediately.
Query params
| Param | Required | Description |
|---|---|---|
name | yes | Secret name (for example exampleApiKey). |
description | no | Human-readable description shown in the UI. |
expiresAt | no | Optional. Kody’s cutoff for sending the secret, separate from the provider token’s own expiration. UTC ISO (2026-12-01T00:00:00.000Z) or a YYYY-MM-DD date stored as midnight UTC. Prefills Expires. Leave omitted and Kody keeps the secret until it is deleted. |
allowedHosts | no | Comma-separated hosts to review for approval. |
allowedPackages | no | Comma-separated saved package ids to review for approval. |
scope | no | user (default) or package. |
packageId | no | Required when scope=package. Use the saved package id that owns the secret. |
Approval policy reminders
- A prefilled
allowedHostslist is on the form under Where this secret can be sent. Saving writes that list with the secret. - When the save URL omitted hosts, or a later call says a host is not approved,
open
/connect/secrets(name/namesandhosts). Package grants use/account/secrets/approve. hostsmust be hostname-shaped. Truncated or path-bearing values are rejected on that page and are not written toallowedHosts.
Package approval URLs (after a package exists)
Self-authored packages and adopted community forks (communityForkAdopt) can
read and use the user's secrets without an allowed_packages grant; updating or
deleting a user secret from package code still requires that grant. Only the
account owner can add a package to that grant on the secret editor or
/account/secrets/approve — a focused Allow page like /connect/secrets.
secretLock returns that approval URL. Send the link and wait until they
confirm. The grant is written on that page. Removing a grant is also
website-only. When an unadopted community-forked package needs access to one
or more existing user secrets, either adopt it after reviewing the source or
send the approval link so they keep the secrets they already saved.
- Single secret:
/account/secrets/user/{secretName}?package_id={savedPackageId}&package={kodyId} - Multiple secrets for one package (preferred):
/account/secrets/approve?package_id={savedPackageId}&package={kodyId}&names={secret1},{secret2}
Prefer the bulk /account/secrets/approve?...&names=... URL whenever two or
more secrets still need package approval. The account UI shows every listed
secret and lets the user approve them in one click.
Agent instructions
- Generate the URL with the required
nameand any optional params.- When using
scope=package, include the saved package id inpackageId.
- When using
- Ask the user to open the URL in their browser.
- Wait until they confirm the secret is saved.
- If the secret will back a package or package app, run the authenticated smoke
test described in
guide: "integration_bootstrap"before saving the downstream package. - For common non-OAuth integrations, continue with
guide: "secret_backed_integration"after the secret exists. - Proceed using
{{secret:name}}fetch placeholders or a named secret lookup such assecretJwtSign.