Skip to main content
This guide shows how to create a Privy app with an organization secret. Use this flow to provision apps for an existing organization without the Dashboard UI.

Before you begin

Prerequisites:
  • An existing Privy organization
  • The organization_secrets feature enabled for that organization
  • Admin access in the Privy Dashboard
  • The organization ID
  • An organization secret for that organization

Create an organization secret

In the Privy Dashboard, open the organization settings and create an organization secret.
Privy does not store organization secrets. Copy the value at creation time and store it in a secret manager.
Notes:
  • Privy uses the organization ID for API authentication.
  • Each organization can have at most 2 active organization secrets at a time.
  • A secret can include an optional P-256 signing public key.
  • When a signing key is present, every request with that secret must include a valid request signature.

Create an app

Send a POST request to:
The request must include:
  • Authorization: Basic <base64(organization_id:organization_secret)>
  • privy-organization-id: <organization_id>
  • Content-Type: application/json

Example with cURL

Example response

Store the returned app_secret immediately. Like app secrets created in the Dashboard, it cannot be recovered later.

List apps for an organization

List all apps in the organization with:
Example response:

Configure the app

After app creation, use the returned app_id and app_secret to configure the app. Use this app update endpoint:
This request uses app credentials, not organization credentials. Include:
  • Authorization: Basic <base64(app_id:app_secret)>
  • privy-app-id: <app_id>
  • Content-Type: application/json

Enable email and phone login methods

Example response

POST /api/v1/apps/{app_id} is a broad legacy app-settings endpoint. For this flow, the relevant fields are email_auth and sms_auth.
SMS login cannot be enabled when SMS transaction MFA is already enabled for the app. SMS and WhatsApp are also mutually exclusive.

Signed requests

If the organization secret has a signing public key, include two extra headers on every request:
  • privy-request-expiry: a future Unix timestamp in milliseconds
  • privy-authorization-signature: a base64-encoded P-256 signature over the canonical request payload
Sign this canonical JSON payload:

Node.js example

This example uses canonicalize. It matches Privy’s canonical request format.

Troubleshooting

  • If the organization ID in Basic auth does not match the organization ID in the URL, Privy rejects the request.
  • If privy-organization-id is missing or does not match the authenticated organization, Privy rejects the request.
  • A revoked organization secret causes Privy to reject the request.
  • Enabling request signing on a secret causes Privy to reject requests without a valid privy-authorization-signature.