API reference

Wayfinder API

REST endpoints for plan data, Branch deep links, collections, and admin operations.

Base URL

https://wayfinder.youversion.com

Authentication

All endpoints are public. User-scoped routes under /api/user/* require an active session.

Some server-handled endpoints are rate limited. If you receive a 429, honor the Retry-After header before retrying.

Responses are JSON. Check status codes and handle both message and error fields in error payloads.

Braze Delivery

Public CDN-cached endpoints optimized for Braze campaign webhooks. These routes intentionally bypass app proxy so cache hits avoid request-time compute.

GET/api/braze/plans/languages

Returns supported language tags and curated language sets.

Response

{
  "language_tags": ["en", "es", "fr", ...],
  "language_sets": {
    "top4": ["en", "es", "fr", "pt"]
  }
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/languages"
GET/api/braze/plans/details/{id}

Fetches plan details from YouVersion by plan ID.

Response

{
  "id": "81",
  "title": "Bible Plan Name",
  "url": "https://www.bible.com/reading-plans/81"
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/details/81"
GET/api/braze/plans/{planId}

Fetches plan details by plan ID (alias for details).

Response

{
  "id": "46440",
  "title": "Bible Plan Name",
  "url": "https://www.bible.com/reading-plans/46440"
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/46440"
GET/api/braze/plans/collections/{setId}

Returns all collections for a set grouped by language.

Response

{
  "set_id": 2,
  "slug": "prayer",
  "collections": [
    {"language": "en", "collection_id": "12345", "url": "https://www.bible.com/..."}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/collections/2"
GET/api/braze/plans/collections/validate/{setId}

Lightweight validation to confirm a collection set ID exists.

Response

{
  "valid": true,
  "slug": "prayer"
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/collections/validate/2"
GET/api/braze/plans/{planId}/collections

Lists collection sets containing a specific plan.

Response

{
  "plan_id": "46440",
  "collections": [
    {"set_id": "2", "title": "Prayer"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/46440/collections"
GET/api/braze/plans/{planId}/sets/{setId}

Returns whether the plan belongs to the collection set.

Response

{
  "exists": true
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/46440/sets/2"
GET/api/braze/plans/{planId}/in-any-set?ids={setId1,setId2,...}

Returns true if the plan belongs to any of the given collection sets. Accepts 1–20 comma-separated set IDs.

Response

{
  "exists": true
}

Example

curl "https://wayfinder.youversion.com/api/braze/plans/46440/in-any-set?ids=2,3,680"

Plans

Public plan data endpoints with server-side caching.

GET/api/plans/languages

Returns supported language tags and curated language sets.

Response

{
  "language_tags": ["en", "es", "fr", ...],
  "language_sets": {
    "top4": ["en", "es", "fr", "pt"]
  }
}

Example

curl "https://wayfinder.youversion.com/api/plans/languages"
GET/api/plans/details/{id}

Fetches plan details from YouVersion by plan ID.

Response

{
  "id": "81",
  "title": "Bible Plan Name",
  "url": "https://www.bible.com/reading-plans/81"
}

Example

curl "https://wayfinder.youversion.com/api/plans/details/81"
GET/api/plans/collections/{setId}

Returns collections for a set. Add ?refresh=true to bypass cache.

Response

{
  "set_id": 2,
  "slug": "prayer",
  "cached": true,
  "collections": [
    {"language": "en", "collection_id": "12345"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/plans/collections/2"
GET/api/plans/collections/validate/{setId}

Lightweight validation to confirm a collection set ID exists.

Response

{
  "valid": true,
  "slug": "prayer"
}

Example

curl "https://wayfinder.youversion.com/api/plans/collections/validate/2"
GET/api/plans/{planId}/collections

Lists collection sets containing a specific plan.

Response

{
  "plan_id": "46440",
  "collections": [
    {"set_id": "2", "title": "Prayer"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/plans/46440/collections"
GET/api/plans/{planId}/sets/{setId}

Returns whether the plan belongs to the collection set.

Response

{
  "exists": true
}

Example

curl "https://wayfinder.youversion.com/api/plans/46440/sets/2"
POST/api/plans/process

Processes plans for a collection set. Resource-intensive with server-side caching. Admin-only.

Request Body

{
  "set_id": 2,
  "target_langs": ["en", "es"],
  "plan_limit": 24,
  "plan_array_limit": 8
}

Response

{
  "set_id": 2,
  "slug": "prayer",
  "cached": true,
  "plans_by_language": {
    "en": [{"id": "81", "title": "..."}]
  }
}

Example

curl -X POST "https://wayfinder.youversion.com/api/plans/process" \
  -H "Content-Type: application/json" \
  -d '{"set_id": 2, "target_langs": ["en"]}'

Admin Plans

Internal plan management endpoints. Mirror public plan routes with no caching.

GET/api/admin/plans/languages

Returns supported language tags and curated language sets.

Response

{
  "language_tags": ["en", "es", "fr", ...],
  "language_sets": {
    "top4": ["en", "es", "fr", "pt"]
  }
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/languages"
GET/api/admin/plans/details/{id}

Fetches plan details from YouVersion by plan ID.

Response

{
  "id": "81",
  "title": "Bible Plan Name",
  "url": "https://www.bible.com/reading-plans/81"
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/details/81"
GET/api/admin/plans/{planId}

Fetches plan details by plan ID.

Response

{
  "id": "46440",
  "title": "Bible Plan Name",
  "url": "https://www.bible.com/reading-plans/46440"
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/46440"
GET/api/admin/plans/collections/{setId}

Returns collections for a set grouped by language.

Response

{
  "set_id": 2,
  "slug": "prayer",
  "collections": [
    {"language": "en", "collection_id": "12345"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/collections/2"
GET/api/admin/plans/collections/validate/{setId}

Validates that a collection set ID exists.

Response

{
  "valid": true,
  "slug": "prayer"
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/collections/validate/2"
GET/api/admin/plans/{planId}/collections

Lists collection sets containing a specific plan.

Response

{
  "plan_id": "46440",
  "collections": [
    {"set_id": "2", "title": "Prayer"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/46440/collections"
GET/api/admin/plans/{planId}/sets/{setId}

Checks whether a plan belongs to a collection set (direct DB lookup).

Response

{
  "exists": true
}

Example

curl "https://wayfinder.youversion.com/api/admin/plans/46440/sets/2"
POST/api/admin/plans/process

Processes plans for a collection set. No caching — always fetches fresh data.

Request Body

{
  "set_id": 2,
  "target_langs": ["en", "es"],
  "plan_limit": 10000,
  "plan_array_limit": 10000
}

Response

{
  "set_id": 2,
  "slug": "prayer",
  "plans_by_language": {
    "en": [{"id": "81", "title": "..."}]
  }
}

Example

curl -X POST "https://wayfinder.youversion.com/api/admin/plans/process" \
  -H "Content-Type: application/json" \
  -d '{"set_id": 2, "target_langs": ["en"]}'

Plan Collections

Manage plan-to-collection-set mappings.

POST/api/admin/plan-collections

Creates a plan-to-collection mapping.

Request Body

{
  "plan_id": "46440",
  "set_id": "2",
  "title": "Prayer Plan"
}

Response

{
  "success": true,
  "id": "46440_2"
}

Example

curl -X POST "https://wayfinder.youversion.com/api/admin/plan-collections" \
  -H "Content-Type: application/json" \
  -d '{"plan_id": "46440", "set_id": "2", "title": "Prayer Plan"}'
DELETE/api/admin/plan-collections

Deletes a plan-to-collection mapping.

Request Body

{
  "plan_id": "46440",
  "set_id": "2"
}

Response

{
  "success": true
}

Example

curl -X DELETE "https://wayfinder.youversion.com/api/admin/plan-collections" \
  -H "Content-Type: application/json" \
  -d '{"plan_id": "46440", "set_id": "2"}'
POST/api/admin/plan-collections/import

Bulk import/upsert plan-to-collection mappings.

Request Body

{
  "mappings": [
    {"plan_id": "46440", "set_id": "2", "title": "Prayer"}
  ]
}

Response

{
  "success": true,
  "imported": 1
}

Example

curl -X POST "https://wayfinder.youversion.com/api/admin/plan-collections/import" \
  -H "Content-Type: application/json" \
  -d '{"mappings": [{"plan_id": "46440", "set_id": "2", "title": "Prayer"}]}'

Master Collections

Manage the master list of collection sets.

GET/api/master-collections

Lists all master collections.

Response

{
  "collections": [
    {"id": 2, "slug": "prayer", "title": "Prayer", "category": "topic"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/master-collections"
POST/api/master-collections

Adds a new master collection.

Request Body

{
  "id": 99,
  "slug": "new-collection",
  "title": "New Collection",
  "category": "topic"
}

Response

{
  "collections": [...]
}

Example

curl -X POST "https://wayfinder.youversion.com/api/master-collections" \
  -H "Content-Type: application/json" \
  -d '{"id": 99, "slug": "new-collection", "title": "New Collection"}'

Branch / Deep Links

Create Branch.io deep links and fetch link analytics.

POST/api/branch

Creates a Branch.io deep link with the given parameters.

Request Body

{
  "fallbackUrl": "https://www.bible.com/reading-plans/81",
  "campaign": "my-campaign",
  "channel": "email",
  "feature": "reading-plan",
  "tags": ["prayer"],
  "data": {}
}

Response

{
  "url": "https://wayfinder.sc.link/abc123",
  "branchLinkId": "1234567890"
}

Example

curl -X POST "https://wayfinder.youversion.com/api/branch" \
  -H "Content-Type: application/json" \
  -d '{"fallbackUrl": "https://www.bible.com/reading-plans/81", "campaign": "test"}'
GET/api/branch/analytics?linkId={linkId}&startDate={iso}&endDate={iso}

Fetches click analytics for a saved Branch link. Requires active session. Date params optional (default: last 30 days).

Response

{
  "linkId": "abc123",
  "branchLinkId": "1234567890",
  "startDate": "2026-05-06T00:00:00.000Z",
  "endDate": "2026-06-05T00:00:00.000Z",
  "clicks": 150
}

Example

curl "https://wayfinder.youversion.com/api/branch/analytics?linkId=abc123"
POST/api/branch/custom

Creates a Branch.io deep link with explicit desktop/iOS/Android URLs. Admin-only.

Request Body

{
  "url": "https://www.bible.com/reading-plans/81",
  "iosUrl": "https://apps.apple.com/...",
  "androidUrl": "https://play.google.com/...",
  "campaign": "my-campaign",
  "channel": "email",
  "feature": "reading-plan",
  "tags": ["prayer"]
}

Response

{
  "url": "https://wayfinder.sc.link/abc123",
  "branchLinkId": "1234567890"
}

Example

curl -X POST "https://wayfinder.youversion.com/api/branch/custom" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.bible.com/", "campaign": "test"}'

User Data

User-scoped preferences and saved links. Requires an active session.

GET/api/user/versions

Lists the current user's saved Bible versions.

Response

{
  "versions": [
    {"id": "111", "name": "NIV"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/user/versions"
POST/api/user/versions

Adds a Bible version to the user's list.

Request Body

{
  "id": "111",
  "name": "NIV"
}

Response

{
  "versions": [
    {"id": "111", "name": "NIV"}
  ]
}

Example

curl -X POST "https://wayfinder.youversion.com/api/user/versions" \
  -H "Content-Type: application/json" \
  -d '{"id": "111", "name": "NIV"}'
PATCH/api/user/versions

Updates a saved Bible version's name.

Request Body

{
  "id": "111",
  "name": "NIV (Updated)"
}

Response

{
  "versions": [...]
}

Example

curl -X PATCH "https://wayfinder.youversion.com/api/user/versions" \
  -H "Content-Type: application/json" \
  -d '{"id": "111", "name": "NIV (Updated)"}'
DELETE/api/user/versions

Removes a Bible version from the user's list.

Request Body

{
  "id": "111"
}

Response

{
  "versions": [...]
}

Example

curl -X DELETE "https://wayfinder.youversion.com/api/user/versions" \
  -H "Content-Type: application/json" \
  -d '{"id": "111"}'
GET/api/user/collections

Lists the current user's saved collections.

Response

{
  "collections": [
    {"id": 2, "title": "Prayer", "slug": "prayer"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/user/collections"
POST/api/user/collections

Adds a collection to the user's list.

Request Body

{
  "id": 2,
  "title": "Prayer",
  "slug": "prayer"
}

Response

{
  "collections": [...]
}

Example

curl -X POST "https://wayfinder.youversion.com/api/user/collections" \
  -H "Content-Type: application/json" \
  -d '{"id": 2, "title": "Prayer", "slug": "prayer"}'
PATCH/api/user/collections

Updates a saved collection's title.

Request Body

{
  "id": 2,
  "title": "Prayer (Updated)"
}

Response

{
  "collections": [...]
}

Example

curl -X PATCH "https://wayfinder.youversion.com/api/user/collections" \
  -H "Content-Type: application/json" \
  -d '{"id": 2, "title": "Prayer (Updated)"}'
DELETE/api/user/collections

Removes a collection from the user's list.

Request Body

{
  "id": 2
}

Response

{
  "collections": [...]
}

Example

curl -X DELETE "https://wayfinder.youversion.com/api/user/collections" \
  -H "Content-Type: application/json" \
  -d '{"id": 2}'
GET/api/user/links

Lists the current user's saved deep links.

Response

{
  "links": [
    {"id": "abc123", "branchUrl": "https://wayfinder.sc.link/abc", "campaign": "test"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/user/links"
POST/api/user/links

Saves a new deep link to the user's history.

Request Body

{
  "branchUrl": "https://wayfinder.sc.link/abc",
  "fallbackUrl": "https://www.bible.com/...",
  "campaign": "test",
  "channel": "email",
  "feature": "reading-plan",
  "tags": [],
  "data": {},
  "source": "wayfinder",
  "title": "My Link"
}

Response

{
  "id": "abc123",
  "links": [...]
}

Example

curl -X POST "https://wayfinder.youversion.com/api/user/links" \
  -H "Content-Type: application/json" \
  -d '{"branchUrl": "https://wayfinder.sc.link/abc", "fallbackUrl": "https://www.bible.com/reading-plans/81", "campaign": "test"}'

Notifications

Manage Teams webhook notifications for plan processing.

GET/api/admin/notifications

Lists all configured Teams webhooks.

Response

{
  "success": true,
  "webhooks": [
    {"id": "abc", "webhookUrl": "https://...", "channelName": "General"}
  ]
}

Example

curl "https://wayfinder.youversion.com/api/admin/notifications"
POST/api/admin/notifications

Registers a new Teams webhook. Requires active session.

Request Body

{
  "webhookUrl": "https://outlook.office.com/webhook/...",
  "channelName": "General"
}

Response

{
  "success": true,
  "id": "abc123"
}

Example

curl -X POST "https://wayfinder.youversion.com/api/admin/notifications" \
  -H "Content-Type: application/json" \
  -d '{"webhookUrl": "https://outlook.office.com/webhook/...", "channelName": "General"}'
DELETE/api/admin/notifications

Removes a Teams webhook by ID.

Request Body

{
  "webhookId": "abc123"
}

Response

{
  "success": true
}

Example

curl -X DELETE "https://wayfinder.youversion.com/api/admin/notifications" \
  -H "Content-Type: application/json" \
  -d '{"webhookId": "abc123"}'
POST/api/admin/notifications/send

Sends a notification to all active Teams webhooks.

Response

{
  "success": true,
  "message": "Sent to 2 webhooks.",
  "commitCount": 5,
  "sentCount": 2,
  "failedCount": 0
}

Example

curl -X POST "https://wayfinder.youversion.com/api/admin/notifications/send"
POST/api/admin/notifications/test

Sends a test notification to a specific webhook.

Request Body

{
  "webhookId": "abc123"
}

Response

{
  "success": true,
  "message": "Test notification sent successfully."
}

Example

curl -X POST "https://wayfinder.youversion.com/api/admin/notifications/test" \
  -H "Content-Type: application/json" \
  -d '{"webhookId": "abc123"}'

Utility

GET/api/version?id={versionId}

Validates a Bible version ID and returns the abbreviation.

Response

{
  "valid": true,
  "id": "111",
  "name": "NIV"
}

Example

curl "https://wayfinder.youversion.com/api/version?id=111"

Best Practices

  • Use Braze delivery paths under /api/braze/plans/* for cached public reads.
  • Use sensible timeouts and exponential backoff for retries on 429/5xx responses.
  • Limit plan_limit and plan_array_limit to what you need.

JavaScript Example

const res = await fetch(
  "https://wayfinder.youversion.com/api/braze/plans/collections/2"
);
if (!res.ok) {
  const err = await res.json().catch(() => ({}));
  throw new Error(err.message || err.error || "Request failed");
}
const data = await res.json();
console.log(data);

Braze Liquid Builder

Generate connected_content snippets for Braze campaigns. Uses public cache-first delivery routes under /api/braze/plans/*.

List collection sets containing a plan

Reference as {{plan_collections.field_name}} in your message.

Generated Liquid

{% connected_content https://wayfinder.youversion.com/api/braze/plans/{{custom_attribute.${plan_day_last_plan_id}}}/collections
  :method GET
  :content_type application/json
  :save plan_collections
%}