Integrations
Secret setup URL reference
Official Kody doc
Use the hosted /connect/secret-set page whenever the user needs to enter a
secret value such as an API key or personal access token. That page has one job:
set this secret. Secrets stay on the setup page; send the URL and wait until
they confirm save.
In-app "New secret" from /@<slug>/-/secrets opens /@<slug>/-/secrets/new
without query params. Prefill links that include name redirect to
/connect/secret-set so agent links do not land on the general secrets list.
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 /connect/secret-set
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 /connect/secret-set URL and have them paste into Secret value on
that page.
URL format
Provide the user a URL like:
https://<your-kody-origin>/connect/secret-set?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 shown on the setup page. 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/@<slug>/-/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)
Package approval rules live in Secrets
(guide:secrets). resourceLock({ kind: 'secret', name, package_id }) returns
the approval URL. Send the link and wait. For an unadopted community fork, adopt
it after reviewing the source or send the approval link.
- Single secret:
/@<slug>/-/secrets/user/{secretName}?package_id={savedPackageId}&package={kodyId} - Multiple secrets for one package (preferred):
/@<slug>/-/secrets/approve?package_id={savedPackageId}&package={kodyId}&names={secret1},{secret2}
Prefer the bulk /@<slug>/-/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.