Skip to main content
Zap identifies creators through EIP-191 wallet signatures issued via Thirdweb rather than passwords or OAuth tokens. When you connect your wallet, the app exchanges a signed proof for a Supabase Auth session token that is then attached as a bearer token to every subsequent API call. Live runs use that session token to retrieve your provider API keys from encrypted Supabase storage — your keys never leave the server at runtime, and the browser only ever sees masked metadata.
Never paste provider API keys into recipe files (Zap.md, SKILL.md, prompt files) or into environment variables that get committed to source control. All provider credentials must be stored through /settings using the encrypted vault described below. Keys found in committed files are considered compromised and should be rotated immediately.

Connecting Your Wallet

  1. Navigate to /settings in the Zap web app.
  2. Click Connect Wallet and complete the Thirdweb wallet connection flow (MetaMask, Coinbase Wallet, WalletConnect, and other injected providers are supported).
  3. Sign the authentication message when prompted. This signature is an EIP-191 personal sign over a one-time nonce — it does not authorize any on-chain transaction.
  4. The app calls POST /api/auth/wallet-proof with your signed payload. That route proxies the request to the zap-wallet-proof Supabase Edge Function, which:
    • Verifies the EIP-191 signature
    • Records nonce use in the wallet_auth_nonces table to prevent replay attacks
    • Creates or reuses a Supabase Auth user mapped in wallet_auth_users
    • Returns a Supabase Auth session token
  5. The session token is stored in the browser and attached as Authorization: Bearer <token> on all subsequent calls to /api/secrets and /api/zaps/run.
Your wallet address is your creator identity across all Zap surfaces. You can reconnect from any device using the same wallet to access your saved secrets and run history.

Managing Provider Keys

Navigate to /settings and scroll to the Vault section after connecting your wallet. Each supported provider has a corresponding input field.

Supported Secret Types

gmi_api_key
string
GMI Cloud API key. Required for routing image and video generation steps to the GMI provider.
gmi_org_id
string
GMI Cloud organization ID. Required alongside gmi_api_key for billing attribution on GMI runs.
fal_key
string
fal.ai API key. Enables routing to fal.ai for image and video generation steps.
runware_key
string
Runware API key. Enables routing to Runware for image generation steps.
prodia_key
string
Prodia API key. Enables routing to Prodia for image generation steps.
openrouter_key
string
OpenRouter API key. Used for LLM steps that route through OpenRouter.
ai_gateway_api_key
string
AI Gateway API key. Used when routing LLM and multimodal steps through an AI Gateway proxy.

How Keys Are Stored

When you save a key through the UI (or via PUT /api/secrets), the request is forwarded to the zap-user-secrets Supabase Edge Function with your session token. The Edge Function:
  1. Encrypts the plaintext value using USER_SECRETS_ENCRYPTION_KEY before writing it to the user_secrets table
  2. Returns only masked metadata (e.g. key type and last-updated timestamp) to the browser — the plaintext is never returned in any browser-facing response
At runtime, when a live run is dispatched for your account, the Zap server retrieves plaintext keys by calling the same Edge Function with both your authenticated JWT and the x-zap-server-secret header (ZAP_SECRET_REVEAL_TOKEN). This dual-credential requirement means plaintext keys can only be retrieved by the Zap server acting on behalf of an authenticated owner — not by the browser and not by unauthenticated server paths. Do not use legacy profiles.*_api_key columns for Zap provider execution. Those columns are not read by the runtime.

API — Secrets Endpoint

All secrets operations require an Authorization: Bearer <token> header containing a valid Supabase session token obtained from the wallet proof flow.

GET /api/secrets

Returns masked secret metadata for the authenticated creator. If called without a bearer token, returns configuration status only (no secret values).
GET /api/secrets
Authorization: Bearer <supabase-session-token>
{
  "configured": true,
  "project": "wzrdstudio",
  "storage": "supabase.user_secrets",
  "secretTypes": ["gmi_api_key", "gmi_org_id", "fal_key", "runware_key", "prodia_key", "openrouter_key", "ai_gateway_api_key"],
  "secrets": [
    { "secretType": "fal_key", "updatedAt": "2025-01-15T12:00:00Z" }
  ]
}

PUT /api/secrets

Upserts (creates or replaces) an encrypted provider key for the authenticated creator.
PUT /api/secrets
Content-Type: application/json
Authorization: Bearer <supabase-session-token>
{
  "secretType": "fal_key",
  "value": "fal-abc123..."
}
Returns confirmation metadata on success. The plaintext value is encrypted immediately and not echoed back in the response.

DELETE /api/secrets

Removes a stored provider key for the authenticated creator.
DELETE /api/secrets
Content-Type: application/json
Authorization: Bearer <supabase-session-token>
{
  "secretType": "fal_key"
}

For Supabase server-side setup — deploying the zap-user-secrets and zap-wallet-proof Edge Functions and configuring the required encryption secrets — see the Supabase Secrets deployment guide.