Skip to content

Best Practices ​

Tips for building great applications with ApiBiblia.

Caching ​

Cache Bible Content ​

Bible text doesn't change. Cache aggressively:

javascript
// Simple in-memory cache
const verseCache = new Map();

async function getVerse(ref, version = 'rvr60') {
  const key = `${version}:${ref}`;

  if (verseCache.has(key)) {
    return verseCache.get(key);
  }

  const data = await fetchFromApi(ref, version);
  verseCache.set(key, data);
  return data;
}

Use HTTP Caching ​

Our responses include cache headers. Configure your HTTP client to respect them:

javascript
// Using fetch with cache
const response = await fetch(url, {
  headers: { 'X-API-Key': apiKey },
  cache: 'default' // Respects Cache-Control headers
});

Cache Duration Recommendations ​

Content TypeSuggested TTL
Verses & Passages24 hours+
Book lists24 hours
Version lists1 hour
Search results5 minutes

Efficient API Usage ​

Batch Requests ​

Fetch ranges instead of individual verses:

javascript
// Instead of 3 requests
const v1 = await getPassage('Romans 8:28');
const v2 = await getPassage('Romans 8:29');
const v3 = await getPassage('Romans 8:30');

// Make 1 request
const verses = await getPassage('Romans 8:28-30');

Fetch Chapters, Not Verses ​

When displaying full chapters, use the chapters endpoint:

javascript
// Good: 1 request
const chapter = await fetch('/v1/chapters/psa_23');

// Bad: 6 requests
for (let i = 1; i <= 6; i++) {
  await fetch(`/v1/passage?ref=Psalm 23:${i}`);
}

Prefetch Content ​

Anticipate user actions and prefetch:

javascript
// User is viewing John 3, prefetch John 4
if (currentChapter === 'joh_3') {
  prefetch('/v1/chapters/joh_4');
}

Error Handling ​

Always Handle Errors ​

javascript
async function safeGetVerse(ref) {
  try {
    const response = await fetch(`/v1/passage?ref=${ref}`);
    const data = await response.json();

    if (!data.success) {
      console.error('API error:', data.error);
      return null;
    }

    return data.data;
  } catch (error) {
    console.error('Network error:', error);
    return null;
  }
}

Implement Retry Logic ​

javascript
async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);

      if (response.status === 429) {
        const wait = Math.pow(2, i) * 1000;
        await new Promise(r => setTimeout(r, wait));
        continue;
      }

      return response;
    } catch (error) {
      if (i === retries - 1) throw error;
    }
  }
}

Security ​

Keep API Keys Secret ​

Never expose API keys in client-side code:

javascript
// Bad: Key exposed in browser
fetch('/v1/verses/joh_3_16', {
  headers: { 'X-API-Key': 'ab_live_xxx' } // Visible to users!
});

// Good: Proxy through your backend
fetch('/api/verse/joh_3_16'); // Your server adds the API key

Use Environment Variables ​

bash
# .env (never commit this)
APIBIBLIA_API_KEY=ab_live_xxxxx
javascript
// server.js
const apiKey = process.env.APIBIBLIA_API_KEY;

User Experience ​

Show Loading States ​

javascript
function VerseDisplay({ reference }) {
  const [verse, setVerse] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setLoading(true);
    getVerse(reference)
      .then(setVerse)
      .finally(() => setLoading(false));
  }, [reference]);

  if (loading) return <Skeleton />;
  return <VerseText verse={verse} />;
}

Handle Offline Gracefully ​

javascript
async function getVerseWithFallback(ref) {
  try {
    // Try network first
    const data = await fetchFromApi(ref);
    localStorage.setItem(`verse:${ref}`, JSON.stringify(data));
    return data;
  } catch (error) {
    // Fall back to cached version
    const cached = localStorage.getItem(`verse:${ref}`);
    if (cached) return JSON.parse(cached);
    throw error;
  }
}

Support Multiple Languages ​

Both Spanish and English book names work:

javascript
// These are equivalent
getPassage('John 3:16');
getPassage('Juan 3:16');

Monitoring ​

Track API Usage ​

javascript
let apiCalls = 0;

async function trackedFetch(url) {
  apiCalls++;
  console.log(`API call #${apiCalls}: ${url}`);
  return fetch(url);
}

Monitor Rate Limits ​

javascript
async function fetchAndMonitor(url) {
  const response = await fetch(url);

  const remaining = response.headers.get('X-RateLimit-Remaining');
  if (remaining < 10) {
    console.warn(`Low rate limit: ${remaining} requests remaining`);
  }

  return response;
}

Built on Cloudflare's global edge network.