Algolia Debug Bundle
Overview
Collect all necessary diagnostic information for Algolia support tickets or internal troubleshooting. Uses real Algolia API endpoints to gather index stats, key permissions, and query performance data.
Prerequisites
ALGOLIA_APP_ID and ALGOLIA_ADMIN_KEY environment variables set
curl and jq available
- Permission to read API key ACLs and index settings
Instructions
Step 1: Create the Debug Bundle Script
#!/bin/bash
# algolia-debug-bundle.sh
set -euo pipefail
APP_ID="${ALGOLIA_APP_ID:?Set ALGOLIA_APP_ID}"
API_KEY="${ALGOLIA_ADMIN_KEY:?Set ALGOLIA_ADMIN_KEY}"
BUNDLE_DIR="algolia-debug-$(date +%Y%m%d-%H%M%S)"
BASE_URL="https://${APP_ID}-dsn.algolia.net"
HEADERS=(-H "X-Algolia-Application-Id: ${APP_ID}" -H "X-Algolia-API-Key: ${API_KEY}")
mkdir -p "$BUNDLE_DIR"
echo "=== Algolia Debug Bundle ===" | tee "$BUNDLE_DIR/summary.txt"
echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)" | tee -a "$BUNDLE_DIR/summary.txt"
echo "App ID: $APP_ID" | tee -a "$BUNDLE_DIR/summary.txt"
# 1. List all indices with record counts
echo "--- Indices ---" >> "$BUNDLE_DIR/summary.txt"
curl -s "${BASE_URL}/1/indexes" "${HEADERS[@]}" \
| jq '.items[] | {name, entries, dataSize, lastBuildTimeS}' \
> "$BUNDLE_DIR/indices.json" 2>/dev/null
echo "Indices saved" >> "$BUNDLE_DIR/summary.txt"
# 2. Check API key permissions (redacted key)
echo "--- API Key ACL ---" >> "$BUNDLE_DIR/summary.txt"
curl -s "${BASE_URL}/1/keys" "${HEADERS[@]}" \
| jq '.keys[] | {description, acl, indexes, maxQueriesPerIPPerHour, validity}' \
> "$BUNDLE_DIR/api-keys-acl.json" 2>/dev/null
echo "Key ACLs saved (keys redacted)" >> "$BUNDLE_DIR/summary.txt"
# 3. Get recent query logs (last 1000)
echo "--- Query Logs ---" >> "$BUNDLE_DIR/summary.txt"
curl -s "${BASE_URL}/1/logs?length=100&type=all" "${HEADERS[@]}" \
| jq '.logs[] | {timestamp, method, url, answer_code, processing_time_ms, query_nb_hits}' \
> "$BUNDLE_DIR/query-logs.json" 2>/dev/null
echo "Last 100 log entries saved" >> "$BUNDLE_DIR/summary.txt"
# 4. Network connectivity test
echo "--- Network Diagnostics ---" >> "$BUNDLE_DIR/summary.txt"
for host in "${APP_ID}-dsn.algolia.net" "${APP_ID}-1.algolianet.com" "${APP_ID}-2.algolianet.com"; do
RESULT=$(curl -s -o /dev/null -w "%{http_code},%{time_total}" "https://${host}/1/indexes" "${HEADERS[@]}" 2>/dev/null || echo "FAILED")
echo " ${host}: ${RESULT}" >> "$BUNDLE_DIR/summary.txt"
done
# 5. SDK version
echo "--- Environment ---" >> "$BUNDLE_DIR/summary.txt"
node --version >> "$BUNDLE_DIR/summary.txt" 2>/dev/null || echo "node: not found" >> "$BUNDLE_DIR/summary.txt"
npm list algoliasearch 2>/dev/null >> "$BUNDLE_DIR/summary.txt" || echo "algoliasearch: not installed" >> "$BUNDLE_DIR/summary.txt"
# 6. Algolia service status
echo "--- Algolia Status ---" >> "$BUNDLE_DIR/summary.txt"
curl -s https://status.algolia.com/api/v2/status.json \
| jq -r '.status.description' >> "$BUNDLE_DIR/summary.txt" 2>/dev/null
# Package (API keys already excluded from raw responses)
tar -czf "${BUNDLE_DIR}.tar.gz" "$BUNDLE_DIR"
rm -rf "$BUNDLE_DIR"
echo ""
echo "Bundle created: ${BUNDLE_DIR}.tar.gz"
Step 2: Programmatic Debug Data Collection
import { algoliasearch } from 'algoliasearch';
async function collectDebugInfo() {
const client = algoliasearch(
process.env.ALGOLIA_APP_ID!,
process.env.ALGOLIA_ADMIN_KEY!
);
const debug: Record<string, any> = {};
// Index list and stats
const { items } = await client.listIndices();
debug.indices = items.map(i => ({
name: i.name,
entries: i.entries,
dataSize: i.dataSize,
lastBuildTimeS: i.lastBuildTimeS,
}));
// Per-index settings for problematic index
const indexName = 'products'; // Target index
try {
debug.settings = await client.getSettings({ indexName });
} catch (e) {
debug.settings = `Failed: ${e}`;
}
// Recent logs
const { logs } = await client.getLogs({
indexName,
length: 50,
type: 'error', // 'all' | 'query' | 'build' | 'error'
});
debug.recentErrors = logs.map(l => ({
timestamp: l.timestamp,
method: l.method,
answerCode: l.answer_code,
processingTimeMs: l.processing_time_ms,
}));
// API key used (check its ACL)
try {
const keyInfo = await client.getApiKey({
key: process.env.ALGOLIA_ADMIN_KEY!,
});
debug.currentKeyAcl = keyInfo.acl;
} catch (e) {
debug.currentKeyAcl = 'Unable to read key ACL';
}
return debug;
}
Sensitive Data Handling
ALWAYS REDACT before sharing:
- Full API keys (only share last 4 chars)
- User PII in query logs
- Internal hostnames or IPs
Safe to include:
- App ID (it's in every frontend bundle)
- Error codes and status codes
- Index names and record counts
- SDK and Node.js versions
- Processing times and latencies
Error Handling
| Issue |
Cause |
Solution |
getLogs returns empty |
Logs retention is 7 days (Grow) or 30 days (Premium) |
Run sooner after incident |
getApiKey 403 |
Non-admin key can only read its own info |
Use Admin key |
curl returns 000 |
DNS or firewall blocking |
Check outbound HTTPS to *.algolia.net |
No jq available |
Not installed |
apt install jq or parse JSON differently |
Resources
Next Steps
For rate limit issues, see algolia-rate-limits.
1---2name: algolia-debug-bundle3description: |4 Collect Algolia debug evidence: index stats, API key ACLs, query logs,5 and network diagnostics for support tickets.6 Trigger: "algolia debug", "algolia support bundle", "collect algolia logs",7 "algolia diagnostic", "algolia troubleshoot".8allowed-tools: Read, Bash(curl:*), Bash(npm:*), Bash(tar:*), Bash(jq:*), Grep9version: 1.0.010license: MIT11author: Jeremy Longshore <jeremy@intentsolutions.io>12tags: [saas, search, algolia]13compatible-with: claude-code14---1516# Algolia Debug Bundle1718## Overview1920Collect all necessary diagnostic information for Algolia support tickets or internal troubleshooting. Uses real Algolia API endpoints to gather index stats, key permissions, and query performance data.2122## Prerequisites2324- `ALGOLIA_APP_ID` and `ALGOLIA_ADMIN_KEY` environment variables set25- `curl` and `jq` available26- Permission to read API key ACLs and index settings2728## Instructions2930### Step 1: Create the Debug Bundle Script3132```bash33#!/bin/bash34# algolia-debug-bundle.sh35set -euo pipefail3637APP_ID="${ALGOLIA_APP_ID:?Set ALGOLIA_APP_ID}"38API_KEY="${ALGOLIA_ADMIN_KEY:?Set ALGOLIA_ADMIN_KEY}"39BUNDLE_DIR="algolia-debug-$(date +%Y%m%d-%H%M%S)"40BASE_URL="https://${APP_ID}-dsn.algolia.net"41HEADERS=(-H "X-Algolia-Application-Id: ${APP_ID}" -H "X-Algolia-API-Key: ${API_KEY}")4243mkdir -p "$BUNDLE_DIR"4445echo "=== Algolia Debug Bundle ===" | tee "$BUNDLE_DIR/summary.txt"46echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)" | tee -a "$BUNDLE_DIR/summary.txt"47echo "App ID: $APP_ID" | tee -a "$BUNDLE_DIR/summary.txt"4849# 1. List all indices with record counts50echo "--- Indices ---" >> "$BUNDLE_DIR/summary.txt"51curl -s "${BASE_URL}/1/indexes" "${HEADERS[@]}" \52 | jq '.items[] | {name, entries, dataSize, lastBuildTimeS}' \53 > "$BUNDLE_DIR/indices.json" 2>/dev/null54echo "Indices saved" >> "$BUNDLE_DIR/summary.txt"5556# 2. Check API key permissions (redacted key)57echo "--- API Key ACL ---" >> "$BUNDLE_DIR/summary.txt"58curl -s "${BASE_URL}/1/keys" "${HEADERS[@]}" \59 | jq '.keys[] | {description, acl, indexes, maxQueriesPerIPPerHour, validity}' \60 > "$BUNDLE_DIR/api-keys-acl.json" 2>/dev/null61echo "Key ACLs saved (keys redacted)" >> "$BUNDLE_DIR/summary.txt"6263# 3. Get recent query logs (last 1000)64echo "--- Query Logs ---" >> "$BUNDLE_DIR/summary.txt"65curl -s "${BASE_URL}/1/logs?length=100&type=all" "${HEADERS[@]}" \66 | jq '.logs[] | {timestamp, method, url, answer_code, processing_time_ms, query_nb_hits}' \67 > "$BUNDLE_DIR/query-logs.json" 2>/dev/null68echo "Last 100 log entries saved" >> "$BUNDLE_DIR/summary.txt"6970# 4. Network connectivity test71echo "--- Network Diagnostics ---" >> "$BUNDLE_DIR/summary.txt"72for host in "${APP_ID}-dsn.algolia.net" "${APP_ID}-1.algolianet.com" "${APP_ID}-2.algolianet.com"; do73 RESULT=$(curl -s -o /dev/null -w "%{http_code},%{time_total}" "https://${host}/1/indexes" "${HEADERS[@]}" 2>/dev/null || echo "FAILED")74 echo " ${host}: ${RESULT}" >> "$BUNDLE_DIR/summary.txt"75done7677# 5. SDK version78echo "--- Environment ---" >> "$BUNDLE_DIR/summary.txt"79node --version >> "$BUNDLE_DIR/summary.txt" 2>/dev/null || echo "node: not found" >> "$BUNDLE_DIR/summary.txt"80npm list algoliasearch 2>/dev/null >> "$BUNDLE_DIR/summary.txt" || echo "algoliasearch: not installed" >> "$BUNDLE_DIR/summary.txt"8182# 6. Algolia service status83echo "--- Algolia Status ---" >> "$BUNDLE_DIR/summary.txt"84curl -s https://status.algolia.com/api/v2/status.json \85 | jq -r '.status.description' >> "$BUNDLE_DIR/summary.txt" 2>/dev/null8687# Package (API keys already excluded from raw responses)88tar -czf "${BUNDLE_DIR}.tar.gz" "$BUNDLE_DIR"89rm -rf "$BUNDLE_DIR"90echo ""91echo "Bundle created: ${BUNDLE_DIR}.tar.gz"92```9394### Step 2: Programmatic Debug Data Collection9596```typescript97import { algoliasearch } from 'algoliasearch';9899async function collectDebugInfo() {100 const client = algoliasearch(101 process.env.ALGOLIA_APP_ID!,102 process.env.ALGOLIA_ADMIN_KEY!103 );104105 const debug: Record<string, any> = {};106107 // Index list and stats108 const { items } = await client.listIndices();109 debug.indices = items.map(i => ({110 name: i.name,111 entries: i.entries,112 dataSize: i.dataSize,113 lastBuildTimeS: i.lastBuildTimeS,114 }));115116 // Per-index settings for problematic index117 const indexName = 'products'; // Target index118 try {119 debug.settings = await client.getSettings({ indexName });120 } catch (e) {121 debug.settings = `Failed: ${e}`;122 }123124 // Recent logs125 const { logs } = await client.getLogs({126 indexName,127 length: 50,128 type: 'error', // 'all' | 'query' | 'build' | 'error'129 });130 debug.recentErrors = logs.map(l => ({131 timestamp: l.timestamp,132 method: l.method,133 answerCode: l.answer_code,134 processingTimeMs: l.processing_time_ms,135 }));136137 // API key used (check its ACL)138 try {139 const keyInfo = await client.getApiKey({140 key: process.env.ALGOLIA_ADMIN_KEY!,141 });142 debug.currentKeyAcl = keyInfo.acl;143 } catch (e) {144 debug.currentKeyAcl = 'Unable to read key ACL';145 }146147 return debug;148}149```150151## Sensitive Data Handling152153**ALWAYS REDACT before sharing:**154- Full API keys (only share last 4 chars)155- User PII in query logs156- Internal hostnames or IPs157158**Safe to include:**159- App ID (it's in every frontend bundle)160- Error codes and status codes161- Index names and record counts162- SDK and Node.js versions163- Processing times and latencies164165## Error Handling166167| Issue | Cause | Solution |168|-------|-------|----------|169| `getLogs` returns empty | Logs retention is 7 days (Grow) or 30 days (Premium) | Run sooner after incident |170| `getApiKey` 403 | Non-admin key can only read its own info | Use Admin key |171| curl returns `000` | DNS or firewall blocking | Check outbound HTTPS to `*.algolia.net` |172| No `jq` available | Not installed | `apt install jq` or parse JSON differently |173174## Resources175176- [Algolia Logs API](https://www.algolia.com/doc/api-reference/api-methods/get-logs/)177- [Algolia Status Page](https://status.algolia.com)178- [Algolia Support](https://support.algolia.com)179180## Next Steps181182For rate limit issues, see `algolia-rate-limits`.183