API Reference
GospeLib exposes a REST + JSON API through a single gateway. This page covers everything you need to start making requests.
Base URL
All traffic enters through the API gateway:
https://<gateway-host>/api/v1/
During local development the gateway runs at http://localhost:8080/api/v1/.
No service is exposed directly — every request is proxied by the gateway, which handles authentication, rate limiting, request ID injection, and CORS.
Authentication
GospeLib uses Clerk for identity. Authenticated requests must include a Bearer token in the Authorization header:
GET /api/v1/passages/gen.1.1 HTTP/1.1
Host: api.gospelib.com
Authorization: Bearer <JWT>
The gateway validates the JWT signature, extracts user claims, and injects two headers into every downstream request:
| Header | Description |
|---|---|
X-Request-ID | Unique request identifier (UUID) — use for support tickets and log correlation |
X-User-Id | Authenticated user's ID (from JWT sub claim) |
Public endpoints (health checks, plan listing) do not require authentication.
Response Envelope
Every response follows a consistent envelope format.
Success
{
"data": {
/* resource payload */
},
"meta": {
"total": 150,
"next_cursor": "eyJpZCI6MTUwfQ=="
}
}
| Field | Type | Description |
|---|---|---|
data | T | The requested resource or collection |
meta.total | number? | Total count (when available) |
meta.next_cursor | string? | Opaque cursor for the next page |
Error
{
"error": {
"code": "PASSAGE_NOT_FOUND",
"message": "Passage not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"details": {}
}
}
| Field | Type | Description |
|---|---|---|
error.code | string | Machine-readable UPPER_SNAKE code (see Error Codes) |
error.message | string | Human-readable description |
error.request_id | string | Matches the X-Request-ID header |
error.details | object? | Additional context (e.g., field-level validation errors) |
Pagination
All list endpoints use cursor-based pagination. Pass the next_cursor value from the previous response as the cursor query parameter:
GET /api/v1/topics?cursor=eyJpZCI6MTUwfQ==
If meta.next_cursor is absent, you have reached the last page.
Cursor-based pagination is more reliable than offset-based pagination for datasets that change frequently. Cursors remain stable across inserts and deletes.
Rate Limiting
The gateway enforces per-user, per-endpoint rate limits. Limits vary by subscription tier:
| Endpoint Group | Free Tier | Paid Tier |
|---|---|---|
| Passages | 60 req/min | 600 req/min |
| Search | 20 req/min | 200 req/min |
| Lexicon | 40 req/min | 400 req/min |
| AI | 5 req/hr | 50 req/hr |
When rate-limited, the API returns a 429 status with the RATE_LIMITED error code. Retry after the window resets.
Service APIs
The gateway routes requests to backend services based on URL prefix:
| API | Prefix | Service | Description |
|---|---|---|---|
| Content | /api/v1/passages, /api/v1/lexicon, /api/v1/topics, /api/v1/search | content | Scripture text, lexicon, topics, graph, search |
| Auth | /api/v1/users | auth | User profiles, JWT, Clerk webhooks |
| Billing | /api/v1/billing | billing | Subscriptions, entitlements, Stripe |
| AI | /api/v1/ai | ai | Passage explanation, study questions |
| Notifications | /api/v1/notifications | notifications | Push tokens, preferences |
Further Reading
- Error Codes — complete error code reference
- Architecture > Communication — service communication patterns, async events, webhook flows