Skip to content
Charming Docs
Esc
navigateopen⌘Jpreview

Create a new secret value

Owner-only, write-only. Creates a new encrypted secret value under a name. The name must match ^[A-Z][A-Z0-9_]*$ (the same charset a {{secret:NAME}} reference uses, so a settable name is always referenceable); values are capped at 8 KiB. The value is never echoed back. Returns 409 secret_already_exists if a secret with the same name already exists for this scope; use PUT to replace it. Requires the owner’s user token; app/render tokens are rejected.

POST/app/{id}/secrets
Authorization
AuthorizationBearer token (bld_user_*) · headerrequired
User-scoped personal access token. Mint via `POST /api/token` after signing in, or via the device-pairing flow at `POST /api/pair/start`. Authorises everything the user can do.
Path parameters
idstringrequired
Request body
requiredapplication/json
namestringrequired
Env-var-shaped secret name (referenceable via `{{secret:NAME}}`).
matches ^[A-Z][A-Z0-9_]*$
valuestringrequired
Plaintext secret value (max 8 KiB). Stored encrypted; never returned.
max length 8192
Responses
200Secret stored.
okbooleanrequired
Allowed:true
400Body is not JSON, name/value missing, name invalid, or value too large.
okbooleanrequired
Allowed:false
errorobjectrequired
Show properties
kindstringrequired
Stable enum-shaped error key. Branch on this for recovery flows.
Allowed:not_foundunknown_operationoperation_not_foundoperation_failedunauthorizedtoken_expiredforbiddenforbidden_writestorage_quota_exceededinvalid_moduleinvalid_uiinvalid_route_schemainvalid_routes_shapeinvalid_manifest_exportsinvalid_requestinvalid_inputinvalid_outputunexpected_keyscapability_deniedcapability_errorexecutor_errorinvalid_call_shapealready_claimedduplicate_remixmanifest_not_foundpayload_too_largemodule_too_largeui_too_largedescription_too_longmissing_descriptioninvalid_descriptionrate_limitedtoo_many_requestsexpiredalready_approvedanon_not_remixableinvalid_if_matchprecondition_requiredversion_mismatchold_string_not_foundold_string_not_uniqueedits_too_largemanifest_id_conflictmanifest_id_immutabletext_too_largestructured_data_too_largeapp_not_foundasset_too_largeasset_count_exceededasset_quota_exceededasset_invalid_keyasset_invalid_content_typeasset_errorinvalid_idsse_cookie_expiredinvalid_secret_namesecret_too_largesecret_already_existsinvalid_iconteam_slug_takenalready_membergrantee_not_foundinvite_cap_reachedread_onlyhandle_takeninvalid_handlename_takenapp_unclaimedlink_cap_reachedgrantee_is_owneralready_invited
messagestring
reasonstring
Set on 401s to distinguish token failure modes when finer detail is needed. `token_revoked_post_claim` is the post-#1284 surface for a bld_app_* that was invalidated by a claim — the `recovery` field on the same `error` object carries the self-contained pairing-recovery hint the agent should follow instead of creating a new app.
Allowed:token_malformedtoken_unknowntoken_revokedtoken_revoked_post_claim
recoveryRecoveryPair | RecoveryRetry | RecoveryShrink | RecoveryRefetch | RecoveryFixRouteLabel | RecoveryOpenExisting | RecoveryRename
Self-contained recovery hint, branching on `kind`. Attached to error envelopes the agent can self-correct on: `pair` for `token_revoked_post_claim` 401s (#1284), `retry` for 429s, `shrink` for too-large / quota-exceeded 413s, `refetch` for 412 `version_mismatch` / `invalid_if_match` / 428 `precondition_required`, `fix_route_label` for 403 `forbidden_write`, `open_existing` for 409 `duplicate_remix`, and `rename` for 409 `manifest_id_immutable` / `manifest_id_conflict`. Every `instructions` string is a single-paragraph, action-first walk-through. Inlined per ADR 2026-05-06-agent-facing-error-surfaces-self-contain-the-fix.
Show properties
One of:
RecoveryPair
kindstringrequired
Allowed:pair
startstring<uri>required
verification_urlstring<uri>required
instructionsstringrequired
RecoveryRetry
kindstringrequired
Allowed:retry
retry_after_secintegerrequired
Seconds to wait before retrying. Matches the `RateLimit-Reset` and `Retry-After` headers on the same response.
min 0
retry_after_urlstring<uri>required
Absolute URL to retry verbatim once the wait elapses.
instructionsstringrequired
RecoveryShrink
kindstringrequired
Allowed:shrink
fieldstringrequired
Which input tripped the cap.
Allowed:moduleuistylesdescriptiontextstructured_dataasseteditssecretpayload
size_bytesintegerrequired
min 0
cap_bytesintegerrequired
min 0
instructionsstringrequired
RecoveryRefetch
kindstringrequired
Allowed:refetch
refetch_urlstring<uri>required
Absolute URL to GET for the fresh ETag before retrying with a corrected If-Match.
instructionsstringrequired
RecoveryFixRouteLabel
kindstringrequired
Allowed:fix_route_label
instructionsstringrequired
App-code recovery: the fix is in the route declaration, NOT in the request. Retrying the same request will fail again.
RecoveryOpenExisting
kindstringrequired
Allowed:open_existing
existing_app_idstringrequired
existing_urlstring<uri>required
instructionsstringrequired
RecoveryRename
kindstringrequired
Allowed:rename
instructionsstringrequired
401User-scoped auth required.
okbooleanrequired
Allowed:false
errorobjectrequired
Show properties
kindstringrequired
Stable enum-shaped error key. Branch on this for recovery flows.
Allowed:not_foundunknown_operationoperation_not_foundoperation_failedunauthorizedtoken_expiredforbiddenforbidden_writestorage_quota_exceededinvalid_moduleinvalid_uiinvalid_route_schemainvalid_routes_shapeinvalid_manifest_exportsinvalid_requestinvalid_inputinvalid_outputunexpected_keyscapability_deniedcapability_errorexecutor_errorinvalid_call_shapealready_claimedduplicate_remixmanifest_not_foundpayload_too_largemodule_too_largeui_too_largedescription_too_longmissing_descriptioninvalid_descriptionrate_limitedtoo_many_requestsexpiredalready_approvedanon_not_remixableinvalid_if_matchprecondition_requiredversion_mismatchold_string_not_foundold_string_not_uniqueedits_too_largemanifest_id_conflictmanifest_id_immutabletext_too_largestructured_data_too_largeapp_not_foundasset_too_largeasset_count_exceededasset_quota_exceededasset_invalid_keyasset_invalid_content_typeasset_errorinvalid_idsse_cookie_expiredinvalid_secret_namesecret_too_largesecret_already_existsinvalid_iconteam_slug_takenalready_membergrantee_not_foundinvite_cap_reachedread_onlyhandle_takeninvalid_handlename_takenapp_unclaimedlink_cap_reachedgrantee_is_owneralready_invited
messagestring
reasonstring
Set on 401s to distinguish token failure modes when finer detail is needed. `token_revoked_post_claim` is the post-#1284 surface for a bld_app_* that was invalidated by a claim — the `recovery` field on the same `error` object carries the self-contained pairing-recovery hint the agent should follow instead of creating a new app.
Allowed:token_malformedtoken_unknowntoken_revokedtoken_revoked_post_claim
recoveryRecoveryPair | RecoveryRetry | RecoveryShrink | RecoveryRefetch | RecoveryFixRouteLabel | RecoveryOpenExisting | RecoveryRename
Self-contained recovery hint, branching on `kind`. Attached to error envelopes the agent can self-correct on: `pair` for `token_revoked_post_claim` 401s (#1284), `retry` for 429s, `shrink` for too-large / quota-exceeded 413s, `refetch` for 412 `version_mismatch` / `invalid_if_match` / 428 `precondition_required`, `fix_route_label` for 403 `forbidden_write`, `open_existing` for 409 `duplicate_remix`, and `rename` for 409 `manifest_id_immutable` / `manifest_id_conflict`. Every `instructions` string is a single-paragraph, action-first walk-through. Inlined per ADR 2026-05-06-agent-facing-error-surfaces-self-contain-the-fix.
Show properties
One of:
RecoveryPair
kindstringrequired
Allowed:pair
startstring<uri>required
verification_urlstring<uri>required
instructionsstringrequired
RecoveryRetry
kindstringrequired
Allowed:retry
retry_after_secintegerrequired
Seconds to wait before retrying. Matches the `RateLimit-Reset` and `Retry-After` headers on the same response.
min 0
retry_after_urlstring<uri>required
Absolute URL to retry verbatim once the wait elapses.
instructionsstringrequired
RecoveryShrink
kindstringrequired
Allowed:shrink
fieldstringrequired
Which input tripped the cap.
Allowed:moduleuistylesdescriptiontextstructured_dataasseteditssecretpayload
size_bytesintegerrequired
min 0
cap_bytesintegerrequired
min 0
instructionsstringrequired
RecoveryRefetch
kindstringrequired
Allowed:refetch
refetch_urlstring<uri>required
Absolute URL to GET for the fresh ETag before retrying with a corrected If-Match.
instructionsstringrequired
RecoveryFixRouteLabel
kindstringrequired
Allowed:fix_route_label
instructionsstringrequired
App-code recovery: the fix is in the route declaration, NOT in the request. Retrying the same request will fail again.
RecoveryOpenExisting
kindstringrequired
Allowed:open_existing
existing_app_idstringrequired
existing_urlstring<uri>required
instructionsstringrequired
RecoveryRename
kindstringrequired
Allowed:rename
instructionsstringrequired
403Caller does not own this app, or the app is anon-owned.
okbooleanrequired
Allowed:false
errorobjectrequired
Show properties
kindstringrequired
Stable enum-shaped error key. Branch on this for recovery flows.
Allowed:not_foundunknown_operationoperation_not_foundoperation_failedunauthorizedtoken_expiredforbiddenforbidden_writestorage_quota_exceededinvalid_moduleinvalid_uiinvalid_route_schemainvalid_routes_shapeinvalid_manifest_exportsinvalid_requestinvalid_inputinvalid_outputunexpected_keyscapability_deniedcapability_errorexecutor_errorinvalid_call_shapealready_claimedduplicate_remixmanifest_not_foundpayload_too_largemodule_too_largeui_too_largedescription_too_longmissing_descriptioninvalid_descriptionrate_limitedtoo_many_requestsexpiredalready_approvedanon_not_remixableinvalid_if_matchprecondition_requiredversion_mismatchold_string_not_foundold_string_not_uniqueedits_too_largemanifest_id_conflictmanifest_id_immutabletext_too_largestructured_data_too_largeapp_not_foundasset_too_largeasset_count_exceededasset_quota_exceededasset_invalid_keyasset_invalid_content_typeasset_errorinvalid_idsse_cookie_expiredinvalid_secret_namesecret_too_largesecret_already_existsinvalid_iconteam_slug_takenalready_membergrantee_not_foundinvite_cap_reachedread_onlyhandle_takeninvalid_handlename_takenapp_unclaimedlink_cap_reachedgrantee_is_owneralready_invited
messagestring
reasonstring
Set on 401s to distinguish token failure modes when finer detail is needed. `token_revoked_post_claim` is the post-#1284 surface for a bld_app_* that was invalidated by a claim — the `recovery` field on the same `error` object carries the self-contained pairing-recovery hint the agent should follow instead of creating a new app.
Allowed:token_malformedtoken_unknowntoken_revokedtoken_revoked_post_claim
recoveryRecoveryPair | RecoveryRetry | RecoveryShrink | RecoveryRefetch | RecoveryFixRouteLabel | RecoveryOpenExisting | RecoveryRename
Self-contained recovery hint, branching on `kind`. Attached to error envelopes the agent can self-correct on: `pair` for `token_revoked_post_claim` 401s (#1284), `retry` for 429s, `shrink` for too-large / quota-exceeded 413s, `refetch` for 412 `version_mismatch` / `invalid_if_match` / 428 `precondition_required`, `fix_route_label` for 403 `forbidden_write`, `open_existing` for 409 `duplicate_remix`, and `rename` for 409 `manifest_id_immutable` / `manifest_id_conflict`. Every `instructions` string is a single-paragraph, action-first walk-through. Inlined per ADR 2026-05-06-agent-facing-error-surfaces-self-contain-the-fix.
Show properties
One of:
RecoveryPair
kindstringrequired
Allowed:pair
startstring<uri>required
verification_urlstring<uri>required
instructionsstringrequired
RecoveryRetry
kindstringrequired
Allowed:retry
retry_after_secintegerrequired
Seconds to wait before retrying. Matches the `RateLimit-Reset` and `Retry-After` headers on the same response.
min 0
retry_after_urlstring<uri>required
Absolute URL to retry verbatim once the wait elapses.
instructionsstringrequired
RecoveryShrink
kindstringrequired
Allowed:shrink
fieldstringrequired
Which input tripped the cap.
Allowed:moduleuistylesdescriptiontextstructured_dataasseteditssecretpayload
size_bytesintegerrequired
min 0
cap_bytesintegerrequired
min 0
instructionsstringrequired
RecoveryRefetch
kindstringrequired
Allowed:refetch
refetch_urlstring<uri>required
Absolute URL to GET for the fresh ETag before retrying with a corrected If-Match.
instructionsstringrequired
RecoveryFixRouteLabel
kindstringrequired
Allowed:fix_route_label
instructionsstringrequired
App-code recovery: the fix is in the route declaration, NOT in the request. Retrying the same request will fail again.
RecoveryOpenExisting
kindstringrequired
Allowed:open_existing
existing_app_idstringrequired
existing_urlstring<uri>required
instructionsstringrequired
RecoveryRename
kindstringrequired
Allowed:rename
instructionsstringrequired
404App not found.
okbooleanrequired
Allowed:false
errorobjectrequired
Show properties
kindstringrequired
Stable enum-shaped error key. Branch on this for recovery flows.
Allowed:not_foundunknown_operationoperation_not_foundoperation_failedunauthorizedtoken_expiredforbiddenforbidden_writestorage_quota_exceededinvalid_moduleinvalid_uiinvalid_route_schemainvalid_routes_shapeinvalid_manifest_exportsinvalid_requestinvalid_inputinvalid_outputunexpected_keyscapability_deniedcapability_errorexecutor_errorinvalid_call_shapealready_claimedduplicate_remixmanifest_not_foundpayload_too_largemodule_too_largeui_too_largedescription_too_longmissing_descriptioninvalid_descriptionrate_limitedtoo_many_requestsexpiredalready_approvedanon_not_remixableinvalid_if_matchprecondition_requiredversion_mismatchold_string_not_foundold_string_not_uniqueedits_too_largemanifest_id_conflictmanifest_id_immutabletext_too_largestructured_data_too_largeapp_not_foundasset_too_largeasset_count_exceededasset_quota_exceededasset_invalid_keyasset_invalid_content_typeasset_errorinvalid_idsse_cookie_expiredinvalid_secret_namesecret_too_largesecret_already_existsinvalid_iconteam_slug_takenalready_membergrantee_not_foundinvite_cap_reachedread_onlyhandle_takeninvalid_handlename_takenapp_unclaimedlink_cap_reachedgrantee_is_owneralready_invited
messagestring
reasonstring
Set on 401s to distinguish token failure modes when finer detail is needed. `token_revoked_post_claim` is the post-#1284 surface for a bld_app_* that was invalidated by a claim — the `recovery` field on the same `error` object carries the self-contained pairing-recovery hint the agent should follow instead of creating a new app.
Allowed:token_malformedtoken_unknowntoken_revokedtoken_revoked_post_claim
recoveryRecoveryPair | RecoveryRetry | RecoveryShrink | RecoveryRefetch | RecoveryFixRouteLabel | RecoveryOpenExisting | RecoveryRename
Self-contained recovery hint, branching on `kind`. Attached to error envelopes the agent can self-correct on: `pair` for `token_revoked_post_claim` 401s (#1284), `retry` for 429s, `shrink` for too-large / quota-exceeded 413s, `refetch` for 412 `version_mismatch` / `invalid_if_match` / 428 `precondition_required`, `fix_route_label` for 403 `forbidden_write`, `open_existing` for 409 `duplicate_remix`, and `rename` for 409 `manifest_id_immutable` / `manifest_id_conflict`. Every `instructions` string is a single-paragraph, action-first walk-through. Inlined per ADR 2026-05-06-agent-facing-error-surfaces-self-contain-the-fix.
Show properties
One of:
RecoveryPair
kindstringrequired
Allowed:pair
startstring<uri>required
verification_urlstring<uri>required
instructionsstringrequired
RecoveryRetry
kindstringrequired
Allowed:retry
retry_after_secintegerrequired
Seconds to wait before retrying. Matches the `RateLimit-Reset` and `Retry-After` headers on the same response.
min 0
retry_after_urlstring<uri>required
Absolute URL to retry verbatim once the wait elapses.
instructionsstringrequired
RecoveryShrink
kindstringrequired
Allowed:shrink
fieldstringrequired
Which input tripped the cap.
Allowed:moduleuistylesdescriptiontextstructured_dataasseteditssecretpayload
size_bytesintegerrequired
min 0
cap_bytesintegerrequired
min 0
instructionsstringrequired
RecoveryRefetch
kindstringrequired
Allowed:refetch
refetch_urlstring<uri>required
Absolute URL to GET for the fresh ETag before retrying with a corrected If-Match.
instructionsstringrequired
RecoveryFixRouteLabel
kindstringrequired
Allowed:fix_route_label
instructionsstringrequired
App-code recovery: the fix is in the route declaration, NOT in the request. Retrying the same request will fail again.
RecoveryOpenExisting
kindstringrequired
Allowed:open_existing
existing_app_idstringrequired
existing_urlstring<uri>required
instructionsstringrequired
RecoveryRename
kindstringrequired
Allowed:rename
instructionsstringrequired
409A secret with this name already exists; use PUT to replace, or DELETE it first.
okbooleanrequired
Allowed:false
errorobjectrequired
Show properties
kindstringrequired
Stable enum-shaped error key. Branch on this for recovery flows.
Allowed:not_foundunknown_operationoperation_not_foundoperation_failedunauthorizedtoken_expiredforbiddenforbidden_writestorage_quota_exceededinvalid_moduleinvalid_uiinvalid_route_schemainvalid_routes_shapeinvalid_manifest_exportsinvalid_requestinvalid_inputinvalid_outputunexpected_keyscapability_deniedcapability_errorexecutor_errorinvalid_call_shapealready_claimedduplicate_remixmanifest_not_foundpayload_too_largemodule_too_largeui_too_largedescription_too_longmissing_descriptioninvalid_descriptionrate_limitedtoo_many_requestsexpiredalready_approvedanon_not_remixableinvalid_if_matchprecondition_requiredversion_mismatchold_string_not_foundold_string_not_uniqueedits_too_largemanifest_id_conflictmanifest_id_immutabletext_too_largestructured_data_too_largeapp_not_foundasset_too_largeasset_count_exceededasset_quota_exceededasset_invalid_keyasset_invalid_content_typeasset_errorinvalid_idsse_cookie_expiredinvalid_secret_namesecret_too_largesecret_already_existsinvalid_iconteam_slug_takenalready_membergrantee_not_foundinvite_cap_reachedread_onlyhandle_takeninvalid_handlename_takenapp_unclaimedlink_cap_reachedgrantee_is_owneralready_invited
messagestring
reasonstring
Set on 401s to distinguish token failure modes when finer detail is needed. `token_revoked_post_claim` is the post-#1284 surface for a bld_app_* that was invalidated by a claim — the `recovery` field on the same `error` object carries the self-contained pairing-recovery hint the agent should follow instead of creating a new app.
Allowed:token_malformedtoken_unknowntoken_revokedtoken_revoked_post_claim
recoveryRecoveryPair | RecoveryRetry | RecoveryShrink | RecoveryRefetch | RecoveryFixRouteLabel | RecoveryOpenExisting | RecoveryRename
Self-contained recovery hint, branching on `kind`. Attached to error envelopes the agent can self-correct on: `pair` for `token_revoked_post_claim` 401s (#1284), `retry` for 429s, `shrink` for too-large / quota-exceeded 413s, `refetch` for 412 `version_mismatch` / `invalid_if_match` / 428 `precondition_required`, `fix_route_label` for 403 `forbidden_write`, `open_existing` for 409 `duplicate_remix`, and `rename` for 409 `manifest_id_immutable` / `manifest_id_conflict`. Every `instructions` string is a single-paragraph, action-first walk-through. Inlined per ADR 2026-05-06-agent-facing-error-surfaces-self-contain-the-fix.
Show properties
One of:
RecoveryPair
kindstringrequired
Allowed:pair
startstring<uri>required
verification_urlstring<uri>required
instructionsstringrequired
RecoveryRetry
kindstringrequired
Allowed:retry
retry_after_secintegerrequired
Seconds to wait before retrying. Matches the `RateLimit-Reset` and `Retry-After` headers on the same response.
min 0
retry_after_urlstring<uri>required
Absolute URL to retry verbatim once the wait elapses.
instructionsstringrequired
RecoveryShrink
kindstringrequired
Allowed:shrink
fieldstringrequired
Which input tripped the cap.
Allowed:moduleuistylesdescriptiontextstructured_dataasseteditssecretpayload
size_bytesintegerrequired
min 0
cap_bytesintegerrequired
min 0
instructionsstringrequired
RecoveryRefetch
kindstringrequired
Allowed:refetch
refetch_urlstring<uri>required
Absolute URL to GET for the fresh ETag before retrying with a corrected If-Match.
instructionsstringrequired
RecoveryFixRouteLabel
kindstringrequired
Allowed:fix_route_label
instructionsstringrequired
App-code recovery: the fix is in the route declaration, NOT in the request. Retrying the same request will fail again.
RecoveryOpenExisting
kindstringrequired
Allowed:open_existing
existing_app_idstringrequired
existing_urlstring<uri>required
instructionsstringrequired
RecoveryRename
kindstringrequired
Allowed:rename
instructionsstringrequired
Request
curl -X POST "https://charm.ing/app/string/secrets" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "value": "string"
}'
Response
{
  "ok": true
}