YouVersion PlatformYouVersion Platform
PlatformLearn moreBiblesDev Docs
PartnersSupport
  • Overview
  • API Reference
  • SDKs
<  Back to Platform

YouVersion Platform

Build applications and integrate with the world's most popular Bible platform.

Platform Products

  • Platform Portal
  • Developer Documentation
  • App Management

Resources

  • Learn more
  • Support
  • Press inquiries

Legal

  • Privacy Policy
  • Terms of Use

© 2025 YouVersion. All rights reserved.

Getting Started
    YouVersion Platform OverviewAPI Usage
Guides
    Sign-in APIsUSFM ReferenceError Codes
Useful Links
    YouVersionGitHub
Guides

Sign-in APIs

To use YouVersion sign-in from an app or web page, the easiest way to do so is to use our SDKs instead of using the information on this page. This guide walks through the YouVersion OAuth authorization code flow using PKCE, which can be a challenging task and is intended for developing new SDKs or situations where our existing SDKs don't support your tech stack or feature needs.

Pre-auth: Retrieve your app_key

First, create your developer account and register your application at platform.YouVersion.com to obtain an App Key.

  1. Create a new App
  2. Set the callback url
  3. Upon creation, note the app_key. This will be the oauth client_id

Auth Call 1: /authorize

This initiates the auth flow for the end user, who will be redirected to login.youversion.com and, after signing in there, be presented with scopes ("YouVersion wants to share your email with App XYZ").

ANDROID DEVS - Android requires in-browser "user interaction" for authorization to complete. You will need to additionally add param require_user_interaction=true to this call, which will prompt the user to click a continuation button after each login.

Endpoint URL

Code
https://api.youversion.com/auth/authorize

Query Parameters

ParameterDescription
response_typecode
client_idYour app's client ID from the Platform Portal (the app_key)
redirect_uriYour app's callback URL (must match the one registered in the Platform Portal)
scopeSpace-separated list of requested scopes (e.g., openid profile email)
nonceRandom string for replay protection (generate a unique value per request)
stateRandom string for CSRF protection (generate a unique value per request)
code_challengeBase64 URL-encoded SHA256 hash of the code_verifier (for PKCE)
code_challenge_methodS256 (indicates SHA256 hashing)
require_user_interactiontrue Optional param for Android and any platform that requires user interaction to continue sign-in flows

Example Request URL

Code
https://api.youversion.com/auth/authorize ?response_type=code &client_id=12345678 &redirect_uri=http://localhost:8001/demo_app.html &scope=openid%20profile%20email &nonce=e9a2905d-4a99-4820-ae3a-b625f45a7983 &state=Bz0u79kz_yczJqJOMTdFog &code_challenge=bxzOnBbgbSJdOS0TIg &code_challenge_method=S256

Redirect back to client

After the user successfully authenticates and grants consent, they will be redirected (303) back to your App's callback URL with the following query parameters:

ParameterDescription
yvp_idThe user's unique YouVersion Platform ID (UUID)
stateThe same state value you provided in the original request (for CSRF validation)
user_nameThe user's display name
profile_pictureURL to the user's profile picture (via YouVersion image proxy)
user_emailThe user's email address

Example Redirect URL

Code
http://localhost:8001/demo_app.html ?profile_picture=imageproxy.youversionapis.com%2F%7Bavatar.png &state=Bz0u79kz_yczJqJOMTdFog &user_email=bobsmith%40AOL.COM &user_name=Bob%20Smith &yvp_id=123-456-789

Auth Call 2: /callback

After receiving the redirect from step 2, your client app should make a request to the /callback endpoint with the user information received. This data will be used to mint a token for the final step.

Endpoint URL

Code
https://api.youversion.com/auth/callback

Query Parameters

ParameterDescription
stateThe same state value from the previous steps (for validation)
yvp_idThe user's unique YouVersion Platform ID (from the redirect)
user_nameThe user's display name (from the redirect)
profile_pictureURL to the user's profile picture (from the redirect)
user_emailThe user's email address (from the redirect)

Example Request URL

TerminalCode
https://api.youversion.com/auth/callback ?state=Bz0u79kz_yczJqJOMTdFog &yvp_id=123-456-789 &user_name=Bob%20Smith&user_email=bobsmith%40AOL.COM &profile_picture=imageproxy.youversionapis.com%2F%7Bavatar.png

Response

The server will respond with a redirect (302) to your callback URL with the authorization code:

Code
http://localhost:8001/demo_app.html ?code=YAJuAqhm &scope=openid &state=Bz0u79kz_yczJqJOMTdFog

Response Parameters:

  • code: The authorization code to exchange for tokens
  • scope: The granted scopes
  • state: Your original state value for validation

Auth Call 3: /token

Exchange the authorization code from step 3 for access tokens. This is a server-to-server POST request.

Endpoint URL

Code
POST https://api.youversion.com/auth/token

Request Body Parameters

ParameterDescription
grant_typeauthorization_code (OAuth 2.0 grant type)
codeThe authorization code received in step 3
redirect_uriMust match the redirect_uri from step 2
client_idYour app's client ID (the app_key)
code_verifierThe original PKCE code verifier (before hashing for code_challenge)

Example Request

TerminalCode
curl 'https://api.youversion.com/auth/token' \ --data-raw 'grant_type=authorization_code &code=YAJuAqhm &redirect_uri=http%3A%2F%2Flocalhost%3A8001%2Fdemo_app.html &client_id=12345678 &code_verifier=ZN153cyjXzx9BA0'

Response

The server responds with a JSON object containing the access tokens:

Code
{ "access_token": "eyJ...", "token_type": "Bearer", "expires_in": "3599", "refresh_token": "XDO52GWc739", "id_token": "eyJraWQg...", "scope": "openid" }

Response Fields:

  • access_token: The OAuth 2.0 access token (JWT - use in API requests with Authorization: Bearer header)
  • token_type: Always Bearer
  • expires_in: Token lifetime in seconds (typically 3599 = ~1 hour)
  • refresh_token: Token to obtain a new access token when it expires
  • id_token: OpenID Connect ID token (JWT containing user claims like email, name, etc.)
  • scope: The granted scopes

Note: Both access_token and id_token are JSON Web Tokens (JWTs). You can decode them at jwt.io to inspect their claims, but always verify signatures in production.

Post-auth: Extracting user info from the JWT tokens

Once you have the tokens from step 4, you can decode the JWTs to access user information and claims.

Decoding JWTs

To decode and verify JWTs, use a JWT library for your programming language:

  • JavaScript/Node.js: jsonwebtoken, jose
  • Python: PyJWT, python-jose
  • Ruby: jwt
  • Go: golang-jwt/jwt
  • Java: java-jwt, jjwt
  • .NET: System.IdentityModel.Tokens.Jwt

Important: Always verify the JWT signature using the public keys from the YouVersion JWKS endpoint before trusting the claims.

Access Token Claims

The access_token contains user information and authorization details. When decoded, it will look like this:

Code
{ "sub": "3f396bde-8efe-4bf2-95fa-f6afb4cb2", "aud": "9gHSQB4BiZkSjJUA9OiTsNa5dv0fACPjj4NOzXRZ", "name": "Bob Smith", "iss": "https://api.youversion.com", "yvp_id": "123-456-789", "profile_picture": "https://mypicture/bobsmith.png", "exp": 1762916965, "nonce": "e9a2905d-493", "iat": 1762913365, "email": "bobsmith@AOL.COM", "jti": "19e1903d-0d9e-bbf2-eda7437fa02f" }

Key Claims:

ClaimDescription
yvp_idThe user's unique YouVersion Platform ID - use this as the primary user identifier
subSubject - also contains the user's unique ID (same as yvp_id)
emailThe user's email address
nameThe user's display name
profile_pictureURL to the user's profile picture
audAudience - your app's client ID (validates the token is for your app)
issIssuer - the YouVersion API endpoint that issued the token
expExpiration time (Unix timestamp)
iatIssued at time (Unix timestamp)
nonceThe nonce value from your original request (for replay protection)
jtiJWT ID - unique identifier for this token

Best Practice: Use yvp_id as the primary key when storing user information in your database. This ID is stable and unique for each user.

Best Practices and Resources

Security

PKCE Implementation

  • Generate secure random values: Use cryptographically secure random generators for code_verifier (43-128 characters)
  • Never reuse code verifiers: Generate a new one for each authorization flow
  • Store code_verifier securely: Keep it in memory or secure storage until token exchange

State and Nonce

  • Always validate state: Verify the returned state matches what you sent to prevent CSRF attacks
  • Use unique values: Generate a new state and nonce for every authorization request
  • Store temporarily: Associate state with the user's session and validate on callback

Token Security

  • Verify JWT signatures: Always validate tokens using the JWKS endpoint before trusting claims
  • Store tokens securely: Use secure storage (e.g., HTTP-only cookies, encrypted storage) - never in localStorage for web apps
  • Never log tokens: Avoid logging access tokens or refresh tokens in production

Token Management

Access Token Usage

  • Include in API requests: Send as Authorization: Bearer {access_token} header
  • Check expiration: Tokens typically expire in 1 hour - implement refresh logic before expiration
  • Handle 401 errors: When an API returns 401, refresh the token and retry

Refresh Tokens

  • Store securely: Refresh tokens are long-lived and sensitive
  • Implement refresh flow: Use refresh tokens to obtain new access tokens without re-authenticating the user
  • Revoke on logout: Call the token revocation endpoint when users log out

User Data

User Identification

  • Use yvp_id as primary key: Always use yvp_id (not email) as the stable user identifier in your database
  • Don't assume email uniqueness: Users can change emails, so don't rely on email as a primary key
  • Update user info on login: Refresh user profile data (name, email, picture) on each login to stay current

Privacy

  • Request minimum scopes: Only request the scopes your app actually needs
  • Don't share user data: Never share user data with third parties without explicit consent

Testing and Production

  • Test thoroughly: Test the complete flow including error cases (denied consent, expired tokens, network failures)

Error Handling

  • Handle user denial: Gracefully handle when users decline to authorize your app
  • Implement retry logic: Network requests can fail - implement exponential backoff
  • Log errors (not tokens): Log error messages and codes, but never log tokens or sensitive data

Resources

Documentation

  • OAuth 2.0 RFC 6749 - OAuth 2.0 specification
  • PKCE RFC 7636 - Proof Key for Code Exchange specification
  • OpenID Connect - OpenID Connect specification
  • JWT.io - JWT decoder and debugger

Libraries

  • JavaScript: @auth0/auth0-spa-js, oidc-client-js
  • Python: authlib, python-jose
  • Ruby: omniauth-oauth2
  • Go: golang.org/x/oauth2
  • Java/Kotlin: AppAuth-Android
  • Swift: AppAuth-iOS (but, using our Swift SDK would be easiest.)
Edit this page
Last modified on February 3, 2026
API UsageUSFM Reference
On this page
  • Pre-auth: Retrieve your app_key
  • Auth Call 1: /authorize
    • Endpoint URL
    • Query Parameters
    • Example Request URL
    • Redirect back to client
    • Example Redirect URL
  • Auth Call 2: /callback
    • Endpoint URL
    • Query Parameters
    • Example Request URL
    • Response
  • Auth Call 3: /token
    • Endpoint URL
    • Request Body Parameters
    • Example Request
    • Response
  • Post-auth: Extracting user info from the JWT tokens
    • Decoding JWTs
    • Access Token Claims
  • Best Practices and Resources
    • Security
    • Token Management
    • User Data
    • Testing and Production
    • Resources
JSON
JSON