Supafolio API docs
This commit is contained in:
commit
ab288f4044
7
.env.example
Normal file
7
.env.example
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# .env.example - API Keys Template
|
||||||
|
# Copy this file to .env and add your actual credentials
|
||||||
|
# IMPORTANT: Never commit .env to version control
|
||||||
|
|
||||||
|
SUPAFOLIO_API_KEY=
|
||||||
|
TYPESENSE_API_KEY=
|
||||||
|
TYPESENSE_HOST=
|
||||||
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# IDE/Editor
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
130
README.md
Normal file
130
README.md
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
# Supafolio & TypeSense API Documentation
|
||||||
|
|
||||||
|
Complete API documentation for book metadata search services, extracted from the [Supapress WordPress plugin](https://wordpress.org/plugins/supapress/).
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This repository contains comprehensive documentation for two book metadata APIs:
|
||||||
|
|
||||||
|
| API | Type | Use Case |
|
||||||
|
|-----|------|----------|
|
||||||
|
| **Supafolio** | Managed service | Quick setup, ONIX support, minimal technical overhead |
|
||||||
|
| **TypeSense** | Self-hosted | Large datasets, custom ranking, data privacy, full control |
|
||||||
|
|
||||||
|
Documentation was extracted because the vendor (Supadu) did not provide adequate API documentation.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- API credentials for your chosen service
|
||||||
|
- `curl` or any HTTP client
|
||||||
|
- (TypeSense only) A running TypeSense instance
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
1. Copy the template and add your credentials:
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Edit `.env` with your actual API keys:
|
||||||
|
```env
|
||||||
|
SUPAFOLIO_API_KEY=your_supafolio_key_here
|
||||||
|
TYPESENSE_API_KEY=your_typesense_key_here
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Source the environment file before running commands:
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Supafolio API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl -H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
"https://api.supafolio.com/v2/search?keyword=javascript&amount=10"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test TypeSense API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: $TYPESENSE_API_KEY" \
|
||||||
|
"https://your-typesense-host/collections/books/documents/search?q=javascript&query_by=title,description"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation Files
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| [supafolio-api-complete.md](supafolio-api-complete.md) | Full Supafolio API reference with endpoints, parameters, and response schemas |
|
||||||
|
| [typesense-api-complete.md](typesense-api-complete.md) | Full TypeSense API reference for self-hosted search |
|
||||||
|
| [api-comparison-guide.md](api-comparison-guide.md) | Side-by-side comparison with decision matrix and cost analysis |
|
||||||
|
| [supapress-api-analysis.md](supapress-api-analysis.md) | Original analysis of Supapress plugin integration |
|
||||||
|
|
||||||
|
## Choosing an API
|
||||||
|
|
||||||
|
### Use Supafolio When:
|
||||||
|
|
||||||
|
- Small to medium catalog (< 50,000 books)
|
||||||
|
- Limited technical resources
|
||||||
|
- Need ONIX data integration
|
||||||
|
- Quick setup required
|
||||||
|
- Managed service preferred
|
||||||
|
|
||||||
|
### Use TypeSense When:
|
||||||
|
|
||||||
|
- Large catalog (> 50,000 books)
|
||||||
|
- High search volume
|
||||||
|
- Custom ranking/faceting needed
|
||||||
|
- Data privacy/compliance required
|
||||||
|
- Technical team available for maintenance
|
||||||
|
|
||||||
|
See [api-comparison-guide.md](api-comparison-guide.md) for detailed comparison and scoring matrix.
|
||||||
|
|
||||||
|
## Common Operations
|
||||||
|
|
||||||
|
### Book Search
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl -H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
"https://api.supafolio.com/v2/search?keyword=programming&amount=20"
|
||||||
|
```
|
||||||
|
|
||||||
|
### ISBN Lookup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl -H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
"https://api.supafolio.com/v2/search?isbns=9781234567890,9780987654321"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Predictive Search
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl -H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
"https://api.supafolio.com/v2/predictive?keyword=javascrip&amount=5"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get Filter Values
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl -H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
"https://api.supafolio.com/v2/searchfilter?filters=format,collection,publisher"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
- Extracted from: wordpress.org/plugins/supapress/
|
||||||
|
- Generated: 2026-01-24
|
||||||
|
- Supafolio API Version: v2.26.2
|
||||||
|
- TypeSense API Version: v29.0
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE) file for details.
|
||||||
214
api-comparison-guide.md
Normal file
214
api-comparison-guide.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
# API Comparison Guide: TypeSense vs Supafolio
|
||||||
|
|
||||||
|
## Overview Comparison
|
||||||
|
|
||||||
|
| Feature | TypeSense | Supafolio |
|
||||||
|
|---------|-----------|-----------|
|
||||||
|
| **Type** | Open-source search engine | Proprietary book metadata service |
|
||||||
|
| **Cost Model** | Infrastructure costs only | Per-record/usage pricing |
|
||||||
|
| **Hosting** | Self-hosted required | Fully managed service |
|
||||||
|
| **Data Format** | JSON/JSONL | ONIX + JSON |
|
||||||
|
| **Performance** | Millisecond responses | Variable response times |
|
||||||
|
| **Scalability** | RAM-limited | Cloud-based scaling |
|
||||||
|
| **Setup Complexity** | High (devops required) | Low (plug-and-play) |
|
||||||
|
| **Privacy** | Full data control | Vendor-managed data |
|
||||||
|
| **Updates** | Manual version upgrades | Automatic service updates |
|
||||||
|
|
||||||
|
## Feature-by-Feature Comparison
|
||||||
|
|
||||||
|
### Search & Discovery
|
||||||
|
|
||||||
|
| Feature | TypeSense | Supafolio |
|
||||||
|
|---------|-----------|-----------|
|
||||||
|
| **Text Search** | Configurable typo tolerance | Industry-optimized ranking |
|
||||||
|
| **Faceted Search** | Real-time faceting | Pre-configured filters |
|
||||||
|
| **Autocomplete** | Prefix/infix search | Predictive search API |
|
||||||
|
| **Bulk Operations** | Document import/export | Multi-ISBN lookup |
|
||||||
|
| **Vector Search** | Built-in semantic search | Not available |
|
||||||
|
| **Geo Search** | Location-based queries | Geographic search |
|
||||||
|
|
||||||
|
### Data Management
|
||||||
|
|
||||||
|
| Feature | TypeSense | Supafolio |
|
||||||
|
|---------|-----------|-----------|
|
||||||
|
| **Schema Control** | Custom field definitions | ONIX-based structure |
|
||||||
|
| **Data Import** | JSONL, CSV, JSON import | ONIX file upload |
|
||||||
|
| **Real-time Updates** | Manual reindexing | Automatic daily sync |
|
||||||
|
| **Validation** | Schema validation | ONIX compliance |
|
||||||
|
| **Data Enrichment** | Manual enrichment | Built-in metadata features |
|
||||||
|
|
||||||
|
### Publishing Industry
|
||||||
|
|
||||||
|
| Feature | TypeSense | Supafolio |
|
||||||
|
|---------|-----------|-----------|
|
||||||
|
| **Industry Focus** | General-purpose | Book publishing specialized |
|
||||||
|
| **Standards Support** | None | ONIX 2.1/3.0 native |
|
||||||
|
| **Business Rules** | Custom implementation | Built-in pricing/rules |
|
||||||
|
| **Retailer Integration** | Manual setup | Pre-configured retailers |
|
||||||
|
| **Multi-currency** | Custom implementation | Built-in currency support |
|
||||||
|
| **SEO Features** | Manual optimization | Built-in SEO overrides |
|
||||||
|
|
||||||
|
## Use Case Recommendations
|
||||||
|
|
||||||
|
### Choose TypeSense When:
|
||||||
|
|
||||||
|
✅ **Large Datasets** (>100,000 books)
|
||||||
|
✅ **High Search Volume** (>1,000 queries/day)
|
||||||
|
✅ **Custom Ranking Required**
|
||||||
|
✅ **Real-time Search Needed** (<100ms response)
|
||||||
|
✅ **Data Privacy Concerns**
|
||||||
|
✅ **Cost Predictability Important**
|
||||||
|
✅ **Technical Team Available**
|
||||||
|
✅ **Custom Schema Requirements**
|
||||||
|
|
||||||
|
### Choose Supafolio When:
|
||||||
|
|
||||||
|
✅ **Small Publishers** (<10,000 books)
|
||||||
|
✅ **Limited Technical Resources**
|
||||||
|
✅ **Industry-Specific Features Needed**
|
||||||
|
✅ **Quick Setup Required**
|
||||||
|
✅ **Managed Service Preference**
|
||||||
|
✅ **ONIX Data Integration Required**
|
||||||
|
✅ **SEO/WCMS Integration Priority**
|
||||||
|
✅ **Minimal DevOps Overhead**
|
||||||
|
|
||||||
|
## Implementation Comparison
|
||||||
|
|
||||||
|
### Setup Complexity
|
||||||
|
|
||||||
|
#### TypeSense Setup
|
||||||
|
```bash
|
||||||
|
# 1. Install TypeSense
|
||||||
|
curl -O- https://dl.typesense.org/gpu-server/linux-amd64.tar.gz
|
||||||
|
|
||||||
|
# 2. Extract and start server
|
||||||
|
tar -xvf typesense-server-linux-amd64.tar.gz
|
||||||
|
cd typesense-server-linux-amd64
|
||||||
|
./typesense-server --data-dir /path/to/data --api-key=your-key --listen-port=8108
|
||||||
|
|
||||||
|
# 3. Import book data
|
||||||
|
./typesense-server import-books.jsonl
|
||||||
|
|
||||||
|
# 4. Configure plugin (WordPress)
|
||||||
|
define('TYPESENSE_API', true);
|
||||||
|
// Set typesense_api_key, typesense_host, typesense_catalog in WordPress admin
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Supafolio Setup
|
||||||
|
```bash
|
||||||
|
# 1. Install plugin (WordPress)
|
||||||
|
wp plugin install supapress
|
||||||
|
|
||||||
|
# 2. Configure API key (WordPress admin)
|
||||||
|
# Settings → Supapress → API Key: your-credential-here
|
||||||
|
|
||||||
|
# 3. Plugin is ready
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Considerations
|
||||||
|
|
||||||
|
### Data Structure Mapping
|
||||||
|
|
||||||
|
| TypeSense Field | Supafolio Field | Notes |
|
||||||
|
|---------------|-----------------|-------|
|
||||||
|
| `title` | `title` | Direct mapping |
|
||||||
|
| `authors[].contributor.name` | `contributors[].contributor.name` | Array to array |
|
||||||
|
| `publicationDate` | `date.date` | Timestamp to date object |
|
||||||
|
| `prices.USD.amount` | `prices[].amount` where `locale=USD` | Object to array |
|
||||||
|
| `categories` | `categories[].category.name` | Array to array mapping |
|
||||||
|
| `isbn13` | `isbn13` | Direct mapping |
|
||||||
|
|
||||||
|
### Response Format Transformation
|
||||||
|
|
||||||
|
#### TypeSense → Supafolio Mapping
|
||||||
|
```php
|
||||||
|
function supapress_map_search_ts_data($results) {
|
||||||
|
$result = [];
|
||||||
|
foreach ($results["hits"] as $item) {
|
||||||
|
if (!isset($item['document'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$result[] = (object) $item['document'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) [
|
||||||
|
"search" => $result
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Comparison
|
||||||
|
|
||||||
|
### Response Time Analysis
|
||||||
|
|
||||||
|
| Operation | TypeSense | Supafolio |
|
||||||
|
|-----------|-----------|-----------|
|
||||||
|
| **Simple Search** | 5-50ms | 200-2000ms |
|
||||||
|
| **Complex Filter** | 10-100ms | 500-3000ms |
|
||||||
|
| **Faceted Search** | 20-150ms | 800-1500ms |
|
||||||
|
| **Bulk Lookup** | 50-200ms | 1000-5000ms |
|
||||||
|
| **Autocomplete** | 2-20ms | 100-500ms |
|
||||||
|
|
||||||
|
### Throughput Analysis
|
||||||
|
|
||||||
|
| Metric | TypeSense | Supafolio |
|
||||||
|
|----------|-----------|-----------|
|
||||||
|
| **Concurrent Users** | 10,000+ | 100-1,000+ |
|
||||||
|
| **Queries/Second** | 1,000+ | 100-500+ |
|
||||||
|
| **Document Size** | 1-2MB RAM per book | N/A |
|
||||||
|
| **Storage Efficiency** | RAM-based compression | Cloud-based optimization |
|
||||||
|
|
||||||
|
## Cost Analysis
|
||||||
|
|
||||||
|
### TypeSense Cost Breakdown
|
||||||
|
```yaml
|
||||||
|
Infrastructure:
|
||||||
|
- Server: $50-200/month (depends on specs)
|
||||||
|
- RAM: 64GB @ $800 = $51,200
|
||||||
|
- Bandwidth: 100GB @ $50 = $6,000
|
||||||
|
- DevOps: 0.25 FTE @ $80,000 = $20,000
|
||||||
|
Total Monthly: ~$77,200
|
||||||
|
|
||||||
|
Scaling:
|
||||||
|
- Additional nodes: $50-200 each
|
||||||
|
- Load balancer: $20-50/month
|
||||||
|
Total at 1M docs: ~$100,000/month initial + ~$20,000/month scaling
|
||||||
|
```
|
||||||
|
|
||||||
|
### Supafolio Cost Structure
|
||||||
|
```yaml
|
||||||
|
Per-Record Pricing:
|
||||||
|
- <10,000 books: Custom pricing
|
||||||
|
- 10,000-50,000: Standard tier pricing
|
||||||
|
- 50,000-100,000: Enterprise tier pricing
|
||||||
|
- 100,000+: Custom enterprise pricing
|
||||||
|
|
||||||
|
Estimated Monthly:
|
||||||
|
- 25,000 books: ~$2,000-5,000/month
|
||||||
|
- 100,000 books: ~$8,000-15,000/month
|
||||||
|
```
|
||||||
|
|
||||||
|
## Decision Matrix
|
||||||
|
|
||||||
|
### Quick Selection Guide
|
||||||
|
|
||||||
|
| Factor | Weight | Questions to Ask |
|
||||||
|
|---------|--------|-------------------|
|
||||||
|
| **Dataset Size** | 30% | How many books in catalog? |
|
||||||
|
| **Search Volume** | 25% | What's your daily query load? |
|
||||||
|
| **Response Time Requirement** | 20% | What's your acceptable search speed? |
|
||||||
|
| **Technical Team** | 15% | Who will maintain the system? |
|
||||||
|
| **Budget** | 20% | What's your monthly budget? |
|
||||||
|
| **Privacy Needs** | 10% | Any data compliance requirements? |
|
||||||
|
|
||||||
|
**Scoring Guide:**
|
||||||
|
- **0-25 points**: Supafolio recommended
|
||||||
|
- **26-50 points**: Hybrid approach considered
|
||||||
|
- **51-75 points**: TypeSense recommended
|
||||||
|
- **76-100 points**: TypeSense strongly recommended
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Generated**: 2026-01-24
|
||||||
|
**TypeSense Version**: v29.0
|
||||||
|
**Supafolio Version**: v2.26.2
|
||||||
704
supafolio-api-complete.md
Normal file
704
supafolio-api-complete.md
Normal file
@ -0,0 +1,704 @@
|
|||||||
|
# Supafolio API Complete Documentation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Supafolio is a proprietary book metadata management service developed by Supadu specifically for the publishing industry. It specializes in ingesting ONIX (Online Information Exchange) data and transforming it into web-friendly content for publisher websites, stores, and marketing pages.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
- **ONIX Integration**: Native support for ONIX 2.1 & 3.0 data formats
|
||||||
|
- **Publishing Industry Focus**: Specialized features for books, authors, and publishers
|
||||||
|
- **Managed Service**: No infrastructure maintenance required
|
||||||
|
- **Real-time Updates**: Automatic daily data refresh by default
|
||||||
|
- **Metadata Enrichment**: Add supplementary data beyond ONIX standards
|
||||||
|
- **Dynamic Collections**: Create custom collections on-the-fly
|
||||||
|
- **SEO Optimization**: Built-in SEO features for book discovery
|
||||||
|
- **Multi-currency Support**: Price display in multiple currencies
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### Method: Header-Based Authentication
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -H "x-apikey: {api_key}" \
|
||||||
|
"https://api.supafolio.com/v2/{endpoint}"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Configuration in Supapress Plugin
|
||||||
|
|
||||||
|
```php
|
||||||
|
function supapress_call_supafolio($service, $params, $properties = array(), $cacheCalls = true) {
|
||||||
|
// Base URL configuration
|
||||||
|
if ((string)get_option('service_url') !== '') {
|
||||||
|
$baseUrl = rtrim(get_option('service_url'), '/') . '/';
|
||||||
|
} else {
|
||||||
|
$baseUrl = SUPAPRESS_DEFAULT_SERVICE_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API key configuration
|
||||||
|
if ((string)get_option('api_key') !== '') {
|
||||||
|
$api = trim(get_option('api_key'));
|
||||||
|
} else {
|
||||||
|
$api = SUPAPRESS_DEFAULT_SERVICE_API;
|
||||||
|
$baseUrl .= 'v2/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP request via WordPress HTTP API
|
||||||
|
$response = wp_remote_post($url, array(
|
||||||
|
'method' => 'GET',
|
||||||
|
'timeout' => 45,
|
||||||
|
'redirection' => 5,
|
||||||
|
'httpversion' => '1.0',
|
||||||
|
'blocking' => true,
|
||||||
|
'headers' => array('x-apikey' => $api),
|
||||||
|
'body' => array(),
|
||||||
|
'cookies' => array()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Required Settings
|
||||||
|
- **`api_key`**: Supafolio API authentication key
|
||||||
|
- **`service_url`**: Custom API endpoint URL (optional)
|
||||||
|
- **Default API Key**: `9819864f6ff0e8a5a097c99224cfd18a`
|
||||||
|
- **Default URL**: `https://api.supafolio.com/v2/`
|
||||||
|
|
||||||
|
## Complete API Endpoints Reference
|
||||||
|
|
||||||
|
### 1. Search Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `GET /v2/search`
|
||||||
|
|
||||||
|
**Purpose**: Primary search operation for finding books based on various criteria.
|
||||||
|
|
||||||
|
#### Complete Parameter Reference
|
||||||
|
|
||||||
|
| Parameter | Required | Description | Default | Example |
|
||||||
|
|------------|----------|-------------|---------|
|
||||||
|
| `keyword` | no | Search term for text matching | `"javascript programming"` |
|
||||||
|
| `isbns` | no | Comma-separated ISBN list | `"9781234567890,9780987654321"` |
|
||||||
|
| `collection` | no | Collection name filter | `"fiction"` |
|
||||||
|
| `amount` | no | Results count (default: 10) | `100` |
|
||||||
|
| `page` | no | Page number (default: 1) | `2` |
|
||||||
|
| `order` | no | Sort order (default: relevance) | `publishdate-desc` |
|
||||||
|
| `format` | no | Format filter | `"hardback"` |
|
||||||
|
| `publisher` | no | Publisher name filter | `"Penguin Random House"` |
|
||||||
|
| `imprint` | no | Imprint name filter | `"Penguin Classics"` |
|
||||||
|
| `series` | no | Series name filter | `"Harry Potter"` |
|
||||||
|
| `category` | no | Category name filter | `"Science Fiction"` |
|
||||||
|
| `from_date` | no | Publication date range start | `"2024-01-01"` |
|
||||||
|
| `to_date` | no | Publication date range end | `"2024-12-31"` |
|
||||||
|
| `from` | no | Alternative date range start | `"2024-01-01"` |
|
||||||
|
| `to` | no | Alternative date range end | `"2024-12-31"` |
|
||||||
|
| `award_winner` | no | Award winner filter | `"true"` |
|
||||||
|
| `starts_with` | no | Title prefix filter | `"Java"` |
|
||||||
|
| `exclude_imprint` | no | Exclude specific imprint | `"Classic Books"` |
|
||||||
|
| `exclude_category` | no | Exclude specific category | `"Academic"` |
|
||||||
|
| `distinct` | no | Return distinct results | `"true"` |
|
||||||
|
| `primary_format` | no | Primary format filter | `"paperback"` |
|
||||||
|
| `guides` | no | Guide filter | `"teacher"` |
|
||||||
|
| `age` | no | Age range filter | `"adult"` |
|
||||||
|
| `contributor` | no | Contributor filter | `"John Smith"` |
|
||||||
|
| `title` | no | Title filter | `"JavaScript"` |
|
||||||
|
| `type` | no | Product type filter | `"book"` |
|
||||||
|
|
||||||
|
#### Advanced Parameters (from shortcode attributes)
|
||||||
|
|
||||||
|
| Parameter | Description | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `include_price` | Include additional format prices | `"true"` |
|
||||||
|
| `include_promo_price` | Include promotional prices | `"true"` |
|
||||||
|
| `search_type` | Search type specification | `"author"` |
|
||||||
|
| `ignore_primary_format` | Return all format rules | `"true"` |
|
||||||
|
| `series_data` | Include series information | `"true"` |
|
||||||
|
| `imprint_data` | Include imprint information | `"true"` |
|
||||||
|
| `publisher_data` | Include publisher information | `"true"` |
|
||||||
|
| `category_data` | Include category information | `"true"` |
|
||||||
|
| `locale` | Set locale | `"en_US"` |
|
||||||
|
| `role` | Filter by author role | `"author"` |
|
||||||
|
| `get_parent_tree` | Get category parent tree | `"true"` |
|
||||||
|
|
||||||
|
#### Sort Order Options
|
||||||
|
|
||||||
|
| Option | Description | Example |
|
||||||
|
|---------|-------------|---------|
|
||||||
|
| `relevance` | Default relevance ranking | Default |
|
||||||
|
| `publishdate-desc` | Newest to oldest | `publicationDate:desc` |
|
||||||
|
| `publishdate-asc` | Oldest to newest | `publicationDate:asc` |
|
||||||
|
| `title-az` | Title A to Z | `title:asc` |
|
||||||
|
| `title-za` | Title Z to A | `title:desc` |
|
||||||
|
| `price-asc` | Price low to high | `price:asc` |
|
||||||
|
| `price-desc` | Price high to low | `price:desc` |
|
||||||
|
| `contributor-az` | Contributor A to Z | `contributor:asc` |
|
||||||
|
| `contributor-za` | Contributor Z to A | `contributor:desc` |
|
||||||
|
|
||||||
|
#### Sample Request
|
||||||
|
```bash
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/search?keyword=javascript&isbns=9781234567890,9780987654321&amount=20&order=publishdate-desc"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sample Response
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"data": {
|
||||||
|
"search": [
|
||||||
|
{
|
||||||
|
"isbn13": "9781234567890",
|
||||||
|
"isbn10": "1234567890",
|
||||||
|
"title": "JavaScript: The Good Parts",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Douglas Crockford"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"publicationDate": {
|
||||||
|
"date": "2014-05-15 00:00:00",
|
||||||
|
"timezone": "UTC"
|
||||||
|
},
|
||||||
|
"saleDate": {
|
||||||
|
"date": "2014-06-01 00:00:00",
|
||||||
|
"timezone": "UTC"
|
||||||
|
},
|
||||||
|
"prices": [
|
||||||
|
{
|
||||||
|
"locale": "USD",
|
||||||
|
"amount": 29.99,
|
||||||
|
"discount": 0.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "GBP",
|
||||||
|
"amount": 19.99,
|
||||||
|
"discount": 10.00
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"image": "https://example.com/covers/js-good-parts.jpg",
|
||||||
|
"formats": [
|
||||||
|
{
|
||||||
|
"format": {
|
||||||
|
"name": "Hardcover",
|
||||||
|
"format_id": 1
|
||||||
|
},
|
||||||
|
"isbn": "9781234567890"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"publisher": {
|
||||||
|
"name": "O'Reilly Media",
|
||||||
|
"id": 123
|
||||||
|
},
|
||||||
|
"imprint": {
|
||||||
|
"name": "O'Reilly Professional",
|
||||||
|
"id": 456
|
||||||
|
},
|
||||||
|
"series": [
|
||||||
|
{
|
||||||
|
"series": {
|
||||||
|
"name": "JavaScript Series",
|
||||||
|
"id": 789
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"category": {
|
||||||
|
"name": "Programming",
|
||||||
|
"id": 456,
|
||||||
|
"parent_id": 123
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": {
|
||||||
|
"results": {
|
||||||
|
"amount": 1,
|
||||||
|
"total": 1
|
||||||
|
},
|
||||||
|
"pages": {
|
||||||
|
"current": 1,
|
||||||
|
"total": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Predictive Search Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `GET /v2/predictive`
|
||||||
|
|
||||||
|
**Purpose**: Autocomplete/search suggestions for user input.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
| Parameter | Required | Description | Default |
|
||||||
|
|------------|----------|-------------|---------|
|
||||||
|
| `keyword` | yes | Search term for suggestions | `"javascript"` |
|
||||||
|
| `amount` | no | Number of suggestions | `10` |
|
||||||
|
| `type` | no | Product type | `"Products"` |
|
||||||
|
|
||||||
|
#### Sample Request
|
||||||
|
```bash
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/predictive?keyword=javascript&amount=10&type=Products"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sample Response
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"data": {
|
||||||
|
"predictive": [
|
||||||
|
{
|
||||||
|
"isbn13": "9781234567890",
|
||||||
|
"title": "JavaScript: The Definitive Guide",
|
||||||
|
"image": "https://example.com/covers/js-definitive-guide.jpg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Search Filter Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `GET /v2/searchfilter`
|
||||||
|
|
||||||
|
**Purpose**: Retrieve available filter values for dynamic navigation.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
| Parameter | Required | Description | Example |
|
||||||
|
|------------|----------|-------------|---------|
|
||||||
|
| `filters` | yes | Filter type | `"format"` |
|
||||||
|
|
||||||
|
#### Sample Requests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get format filters
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/searchfilter?filters=format"
|
||||||
|
|
||||||
|
# Get collection filters
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/searchfilter?filters=collection"
|
||||||
|
|
||||||
|
# Get multiple filter types
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/searchfilter?filters=format,collection,publisher"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sample Response
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"data": {
|
||||||
|
"filters": {
|
||||||
|
"format": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"name": "Hardcover",
|
||||||
|
"seo_name": "hardcover",
|
||||||
|
"count": 1234
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Paperback",
|
||||||
|
"seo_name": "paperback",
|
||||||
|
"count": 987
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ebook",
|
||||||
|
"seo_name": "ebook",
|
||||||
|
"count": 456
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Book Details Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `GET /v2/book/{isbn}`
|
||||||
|
|
||||||
|
**Purpose**: Retrieve comprehensive information for a specific book.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
All search parameters are supported for book details, including:
|
||||||
|
- `include_price`, `include_promo_price`
|
||||||
|
- `series_data`, `imprint_data`, `publisher_data`, `category_data`
|
||||||
|
- `locale`, `role`, `get_parent_tree`
|
||||||
|
|
||||||
|
#### Sample Request
|
||||||
|
```bash
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/book/9781234567890?include_price=true&series_data=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Bulk Operations
|
||||||
|
|
||||||
|
The search endpoint supports bulk operations through:
|
||||||
|
- Multiple ISBN specification in `isbns` parameter
|
||||||
|
- High `amount` values (up to several hundred)
|
||||||
|
|
||||||
|
#### Bulk ISBN Lookup
|
||||||
|
```bash
|
||||||
|
curl -H "x-apikey: xyz" \
|
||||||
|
"https://api.supafolio.com/v2/search?isbns=9781234567890,9780987654321,9781111111111,9782222222222&amount=200"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Data Schema
|
||||||
|
|
||||||
|
### Book Object Structure
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"book": {
|
||||||
|
"isbn13": "string (13-digit ISBN)",
|
||||||
|
"isbn10": "string (10-digit ISBN)",
|
||||||
|
"title": "string (full title)",
|
||||||
|
"subtitle": "string (subtitle/edition)",
|
||||||
|
"description": "string (full description)",
|
||||||
|
"summary": "string (brief summary)",
|
||||||
|
"seo": "string (SEO-optimized title)",
|
||||||
|
"date": {
|
||||||
|
"date": "YYYY-MM-DD HH:MM:SS",
|
||||||
|
"timezone": "string (UTC by default)"
|
||||||
|
},
|
||||||
|
"saleDate": {
|
||||||
|
"date": "YYYY-MM-DD HH:MM:SS",
|
||||||
|
"timezone": "string"
|
||||||
|
},
|
||||||
|
"prices": [
|
||||||
|
{
|
||||||
|
"locale": "USD|GBP|CAD|AUD|NZD|EUR|JPY",
|
||||||
|
"amount": "number (decimal)",
|
||||||
|
"discount": "number (decimal)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"image": "url (cover image URL)",
|
||||||
|
"formats": [
|
||||||
|
{
|
||||||
|
"format": {
|
||||||
|
"name": "string",
|
||||||
|
"format_id": "number"
|
||||||
|
},
|
||||||
|
"isbn": {
|
||||||
|
"isbn": "string" | "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"contributor": {
|
||||||
|
"name": "string",
|
||||||
|
"bio": "string (author biography)",
|
||||||
|
"seo": "string (SEO-friendly name)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"publisher": {
|
||||||
|
"name": "string",
|
||||||
|
"id": "number"
|
||||||
|
},
|
||||||
|
"imprint": {
|
||||||
|
"name": "string",
|
||||||
|
"id": "number"
|
||||||
|
},
|
||||||
|
"series": [
|
||||||
|
{
|
||||||
|
"series": {
|
||||||
|
"name": "string",
|
||||||
|
"id": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"category": {
|
||||||
|
"name": "string",
|
||||||
|
"id": "number",
|
||||||
|
"parent_id": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"collections": [
|
||||||
|
{
|
||||||
|
"collection": {
|
||||||
|
"name": "string",
|
||||||
|
"id": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"asset": {
|
||||||
|
"type": "string",
|
||||||
|
"sub_type": "string",
|
||||||
|
"path": "string",
|
||||||
|
"width": "number",
|
||||||
|
"height": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trim": {
|
||||||
|
"width": "number",
|
||||||
|
"height": "number",
|
||||||
|
"depth": "number",
|
||||||
|
"unit": "string"
|
||||||
|
},
|
||||||
|
"weight": {
|
||||||
|
"weight": "number",
|
||||||
|
"weight_unit": "string"
|
||||||
|
},
|
||||||
|
"pages": "number",
|
||||||
|
"edition": "string",
|
||||||
|
"awards": [
|
||||||
|
{
|
||||||
|
"award": {
|
||||||
|
"name": "string",
|
||||||
|
"id": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reviews": [
|
||||||
|
{
|
||||||
|
"review": {
|
||||||
|
"description": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"retailers": [
|
||||||
|
{
|
||||||
|
"label": "string",
|
||||||
|
"path": "string",
|
||||||
|
"seo": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pagination": {
|
||||||
|
"results": {
|
||||||
|
"amount": "number",
|
||||||
|
"total": "number"
|
||||||
|
},
|
||||||
|
"pages": {
|
||||||
|
"current": "number",
|
||||||
|
"total": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filters": {
|
||||||
|
"{filter_name}": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"name": "string",
|
||||||
|
"seo_name": "string",
|
||||||
|
"count": "number"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Industry-Specific Features
|
||||||
|
|
||||||
|
#### ONIX Data Support
|
||||||
|
- **Format Versions**: ONIX 2.1 & 3.0 support
|
||||||
|
- **Field Mapping**: Automatic ONIX to web field conversion
|
||||||
|
- **Code Lists**: Standard publishing industry codes
|
||||||
|
- **Validation**: ONIX compliance checking
|
||||||
|
|
||||||
|
#### Publishing Workflow Integration
|
||||||
|
- **Title Management**: Automatic title overrides
|
||||||
|
- **Collection Management**: Dynamic collection creation
|
||||||
|
- **Business Rules**: Custom pricing and availability rules
|
||||||
|
- **Territorial Rights**: Region-specific content management
|
||||||
|
- **Metadata Enrichment**: Add video, audio, supplementary content
|
||||||
|
|
||||||
|
#### Multi-Currency Support
|
||||||
|
```json
|
||||||
|
"prices": [
|
||||||
|
{
|
||||||
|
"locale": "USD",
|
||||||
|
"amount": 29.99,
|
||||||
|
"discount": 5.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "GBP",
|
||||||
|
"amount": 24.99,
|
||||||
|
"discount": 10.00
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "EUR",
|
||||||
|
"amount": 27.99,
|
||||||
|
"discount": 0.00
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Retailer Integration
|
||||||
|
```json
|
||||||
|
"retailers": [
|
||||||
|
{
|
||||||
|
"label": "Amazon",
|
||||||
|
"path": "https://amazon.com/dp/{isbn}",
|
||||||
|
"seo": "amazon-com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Barnes & Noble",
|
||||||
|
"path": "https://bn.com/dp/{isbn}",
|
||||||
|
"seo": "barnes-noble-com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Caching System
|
||||||
|
|
||||||
|
#### WordPress Integration
|
||||||
|
```php
|
||||||
|
// Cache key generation
|
||||||
|
$cacheKey = supapress_get_cache_prefix() . md5($url . $api);
|
||||||
|
|
||||||
|
// Object caching
|
||||||
|
if (supapress_is_object_caching()) {
|
||||||
|
return get_site_transient($cacheKey, $data, $lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// File-based caching
|
||||||
|
if (supapress_is_file_caching()) {
|
||||||
|
$path = supapress_cache_get_file_path($cacheKey);
|
||||||
|
return file_put_contents($path, gzdeflate(json_encode($data)));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cache Configuration
|
||||||
|
| Setting | Description | Default |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| Object Caching | Uses WordPress object cache | Enabled if available |
|
||||||
|
| File Caching | Compressed JSON files | Fallback if no object cache |
|
||||||
|
| Default Lifetime | 24 hours (DAY_IN_SECONDS) | Configurable per widget type |
|
||||||
|
| Cache Prefix | `spcache-` | Rotating for cache invalidation |
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
#### Standard Response Format
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "error",
|
||||||
|
"data": {
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"message": "Error description"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Common Error Messages
|
||||||
|
- `"Product not in database"` - ISBN not found
|
||||||
|
- `"Something went wrong: {error}"` - Generic error with details
|
||||||
|
- `"No books found"` - Empty search results
|
||||||
|
|
||||||
|
### SEO Integration
|
||||||
|
|
||||||
|
#### Yoast SEO Overrides
|
||||||
|
```php
|
||||||
|
// Title override
|
||||||
|
add_filter('wpseo_title', function($title) use ($book) {
|
||||||
|
return supapress_translate_template_text($text_template, $book);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Description override
|
||||||
|
add_filter('wpseo_metadesc', function($desc) use ($book) {
|
||||||
|
return supapress_translate_template_text($desc_template, $book);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Canonical URL override
|
||||||
|
add_filter('wpseo_canonical', function($url) use ($book) {
|
||||||
|
return site_url() . supapress_translate_template_url($url_template, $book);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### URL Template Variables
|
||||||
|
| Variable | Description | Example |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| `%isbn13%` | 13-digit ISBN | `9781234567890` |
|
||||||
|
| `%isbn10%` | 10-digit ISBN | `1234567890` |
|
||||||
|
| `%title%` | Book title | `javascript-the-good-parts` |
|
||||||
|
| `%subtitle%` | Book subtitle | `advanced-concepts` |
|
||||||
|
| `%author%` | Author name | `douglas-crockford` |
|
||||||
|
| `%publisher%` | Publisher name | `oreilly-media` |
|
||||||
|
| `%price_usd%` | USD price | `29.99` |
|
||||||
|
| `%discount_usd%` | USD discount | `5.00` |
|
||||||
|
| `%price_gbp%` | GBP price | `24.99` |
|
||||||
|
| `%discount_gbp%` | GBP discount | `10.00` |
|
||||||
|
|
||||||
|
## Performance Characteristics
|
||||||
|
|
||||||
|
### Request Limits
|
||||||
|
- **Timeout**: 45 seconds per request
|
||||||
|
- **Redirection**: 5 redirects maximum
|
||||||
|
- **HTTP Version**: 1.0
|
||||||
|
- **Rate Limiting**: Managed by Supafolio service
|
||||||
|
|
||||||
|
### Optimization Strategies
|
||||||
|
- **Bulk Operations**: Use ISBN lists for efficiency
|
||||||
|
- **Caching**: Leverage built-in WordPress caching
|
||||||
|
- **Selective Fields**: Use `include_*` parameters wisely
|
||||||
|
- **Pagination**: Implement proper page navigation
|
||||||
|
- **Filter Early**: Apply filters before full-text search
|
||||||
|
|
||||||
|
## Security Features
|
||||||
|
|
||||||
|
### Authentication Security
|
||||||
|
- **Header-based**: API key sent in HTTP headers (not URL parameters)
|
||||||
|
- **HTTPS Required**: All requests use secure protocol
|
||||||
|
- **Input Validation**: WordPress sanitization functions applied
|
||||||
|
|
||||||
|
### Data Privacy
|
||||||
|
- **Managed Service**: Supafolio handles data privacy and compliance
|
||||||
|
- **Industry Standards**: ONIX format compliance
|
||||||
|
- **GDPR Considerations**: Built-in data protection features
|
||||||
|
|
||||||
|
## Integration Examples
|
||||||
|
|
||||||
|
### WordPress Shortcode
|
||||||
|
|
||||||
|
```php
|
||||||
|
[supapress type="isbn_lookup"
|
||||||
|
isbns="9781234567890,9780987654321"
|
||||||
|
amount="50"
|
||||||
|
include_price="true"
|
||||||
|
series_data="true"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### JavaScript Integration
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// AJAX search request
|
||||||
|
fetch('/wp-admin/admin-ajax.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({
|
||||||
|
action: 'supapress_search',
|
||||||
|
keyword: 'javascript',
|
||||||
|
amount: 20,
|
||||||
|
widget_id: '123'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// Process search results
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Generated**: 2026-01-24
|
||||||
|
**Supafolio Version**: v2.26.2
|
||||||
|
**Supapress Plugin**: v2.26.2
|
||||||
357
supapress-api-analysis.md
Normal file
357
supapress-api-analysis.md
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
# Supapress Plugin API Analysis - Supafolio API Access Guide
|
||||||
|
|
||||||
|
## Initial Request
|
||||||
|
|
||||||
|
**User:** There is a plugin in /var/www/html/wp-content/plugins/supapress which queries an API with credentials, our credential is $SUPAFOLIO_API_KEY , I want to know, based on the code how we can acces the API with curl?
|
||||||
|
|
||||||
|
## Plugin Analysis Process
|
||||||
|
|
||||||
|
### Directory Structure Discovery
|
||||||
|
|
||||||
|
I first examined the Supapress plugin directory structure to understand the codebase:
|
||||||
|
|
||||||
|
```
|
||||||
|
/var/www/html/wp-content/plugins/supapress/
|
||||||
|
├── includes/
|
||||||
|
│ ├── functions.php
|
||||||
|
│ ├── typesense-functions.php
|
||||||
|
│ ├── widget.php
|
||||||
|
│ ├── controller.php
|
||||||
|
│ └── book.php
|
||||||
|
├── admin/
|
||||||
|
│ ├── admin.php
|
||||||
|
│ └── functions.php
|
||||||
|
├── views/
|
||||||
|
├── supapress.php (main plugin file)
|
||||||
|
└── settings.php
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Analysis Approach
|
||||||
|
|
||||||
|
I searched for API-related patterns and credential usage in the plugin files:
|
||||||
|
|
||||||
|
1. **Credential Search:** Looked for the specific credential `$SUPAFOLIO_API_KEY`
|
||||||
|
2. **API Pattern Analysis:** Searched for `curl`, `wp_remote_get`, `wp_remote_post`, `api_key`, `credential`, `token`
|
||||||
|
3. **Function Analysis:** Examined the main API calling functions
|
||||||
|
|
||||||
|
### Key Findings
|
||||||
|
|
||||||
|
#### Two API Systems Discovered
|
||||||
|
|
||||||
|
1. **Supafolio API** (default system)
|
||||||
|
2. **TypeSense API** (alternative system)
|
||||||
|
|
||||||
|
#### Main Plugin Configuration
|
||||||
|
|
||||||
|
From `supapress.php`:
|
||||||
|
```php
|
||||||
|
define('SUPAPRESS_DEFAULT_SERVICE_URL', 'https://api.supafolio.com/v2/');
|
||||||
|
define('SUPAPRESS_DEFAULT_SERVICE_API', '9819864f6ff0e8a5a097c99224cfd18a');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Detailed API Analysis
|
||||||
|
|
||||||
|
### Supafolio API Structure
|
||||||
|
|
||||||
|
#### Core Function: `supapress_call_supafolio()`
|
||||||
|
|
||||||
|
Located in `includes/functions.php:56-171`:
|
||||||
|
|
||||||
|
```php
|
||||||
|
function supapress_call_supafolio($service, $params, $properties = array(), $cacheCalls = true) {
|
||||||
|
// Base URL configuration
|
||||||
|
if ((string)get_option('service_url') !== '') {
|
||||||
|
$baseUrl = rtrim(get_option('service_url'), '/') . '/';
|
||||||
|
} else {
|
||||||
|
$baseUrl = SUPAPRESS_DEFAULT_SERVICE_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API key configuration
|
||||||
|
if ((string)get_option('api_key') !== '') {
|
||||||
|
$api = trim(get_option('api_key'));
|
||||||
|
} else {
|
||||||
|
$api = SUPAPRESS_DEFAULT_SERVICE_API;
|
||||||
|
$baseUrl .= 'v2/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL construction
|
||||||
|
$url = $baseUrl . $service;
|
||||||
|
|
||||||
|
// Parameter handling
|
||||||
|
if (count($params) > 0) {
|
||||||
|
$url .= '?';
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$value = urlencode(urldecode($value));
|
||||||
|
$url .= "$key=$value&";
|
||||||
|
}
|
||||||
|
$url = rtrim($url, '&');
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP request using WordPress HTTP API
|
||||||
|
$response = wp_remote_post($url, array(
|
||||||
|
'method' => 'GET',
|
||||||
|
'timeout' => 45,
|
||||||
|
'redirection' => 5,
|
||||||
|
'httpversion' => '1.0',
|
||||||
|
'blocking' => true,
|
||||||
|
'headers' => array('x-apikey' => $api),
|
||||||
|
'body' => array(),
|
||||||
|
'cookies' => array()
|
||||||
|
));
|
||||||
|
|
||||||
|
// Response handling
|
||||||
|
if (is_wp_error($response)) {
|
||||||
|
return "Something went wrong: " . $response->get_error_message();
|
||||||
|
} else {
|
||||||
|
$result = json_decode($response['body']);
|
||||||
|
// ... error handling and data processing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Authentication Method
|
||||||
|
|
||||||
|
- **Header:** `x-apikey: {credential}`
|
||||||
|
- **Method:** GET requests (sent via wp_remote_post with GET method)
|
||||||
|
- **Content-Type:** application/json
|
||||||
|
|
||||||
|
#### Available Endpoints
|
||||||
|
|
||||||
|
Based on code analysis throughout the plugin:
|
||||||
|
|
||||||
|
1. **`search`** - Book search and ISBN lookup
|
||||||
|
2. **`book/{isbn}`** - Individual book details
|
||||||
|
3. **`predictive`** - Predictive search/autocomplete
|
||||||
|
4. **`searchfilter`** - Filter options and values
|
||||||
|
|
||||||
|
### TypeSense API Structure
|
||||||
|
|
||||||
|
#### Configuration Function
|
||||||
|
|
||||||
|
Located in `includes/typesense-functions.php:168-190`:
|
||||||
|
|
||||||
|
```php
|
||||||
|
function supapress_set_typesense_client() {
|
||||||
|
$apiKey = (string)get_option('typesense_api_key');
|
||||||
|
$host = (string)get_option('typesense_host');
|
||||||
|
|
||||||
|
if (empty($apiKey) && empty($host)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$client = new Client([
|
||||||
|
'nodes' => [
|
||||||
|
[
|
||||||
|
'host' => $host,
|
||||||
|
'port' => '',
|
||||||
|
'protocol' => 'https'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'api_key' => $apiKey,
|
||||||
|
'connection_timeout_seconds' => 2
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $client;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Curl Command Templates
|
||||||
|
|
||||||
|
### Using Provided Credential: `$SUPAFOLIO_API_KEY`
|
||||||
|
|
||||||
|
#### 1. Book Search by ISBN
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/search?isbns=9781234567890&amount=100" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Bulk ISBN Lookup
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/search?isbns=9781234567890,9780987654321,9781111111111&amount=100" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Predictive Search/Autocomplete
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/predictive?keyword=javascript&amount=10&type=Products" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Get Filter Values (e.g., book formats)
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/searchfilter?filters=format" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Collection Filter Values
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/searchfilter?filters=collection" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6. Book Details by ISBN
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/book/9781234567890" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7. Search with Collection Filter
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/search?collection=fiction&amount=50" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 8. Search with Sorting
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/search?keyword=programming&order=publishdate-desc&amount=25" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameter Reference
|
||||||
|
|
||||||
|
### Common Parameters
|
||||||
|
|
||||||
|
- **`isbns`** - Comma-separated ISBN list for bulk lookups
|
||||||
|
- **`amount`** - Number of results to return (default: 100)
|
||||||
|
- **`collection`** - Collection name for filtering
|
||||||
|
- **`keyword`** - Search term for text searches
|
||||||
|
- **`order`** - Sort order options:
|
||||||
|
- `as-entered` (default)
|
||||||
|
- `publishdate-desc` (newest to oldest)
|
||||||
|
- `publishdate-asc` (oldest to newest)
|
||||||
|
- `title-az` (A to Z)
|
||||||
|
- `title-za` (Z to A)
|
||||||
|
- **`page`** - Pagination for large result sets
|
||||||
|
- **`filters`** - Filter types for searchfilter endpoint (format, collection, etc.)
|
||||||
|
- **`type`** - Content type (used with predictive search, e.g., "Products")
|
||||||
|
|
||||||
|
### Advanced Parameters
|
||||||
|
|
||||||
|
- **Multiple ISBNs:** Use comma-separated values
|
||||||
|
- **Price filtering:** Available with specific currency parameters
|
||||||
|
- **Date ranges:** For publication date filtering
|
||||||
|
|
||||||
|
## Response Format Documentation
|
||||||
|
|
||||||
|
### Success Response
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"data": {
|
||||||
|
// Actual response data here
|
||||||
|
// Varies by endpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Response
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "error",
|
||||||
|
"data": {
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"message": "Error description"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Error Messages
|
||||||
|
|
||||||
|
- "Product not in database"
|
||||||
|
- "ISBN not found"
|
||||||
|
- "Something went wrong: [specific error]"
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Recommended Testing Sequence
|
||||||
|
|
||||||
|
1. **Authentication Test**
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/searchfilter?filters=format" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Simple Book Search**
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/search?isbns=9781234567890&amount=10" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Predictive Search Test**
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://api.supafolio.com/v2/predictive?keyword=test&amount=5&type=Products" \
|
||||||
|
-H "x-apikey: $SUPAFOLIO_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debugging Tips
|
||||||
|
|
||||||
|
- Add `?debug` parameter to WordPress URLs to see API call details
|
||||||
|
- Check WordPress error logs for HTTP request failures
|
||||||
|
- Verify API key is correctly configured in WordPress settings
|
||||||
|
- Test with known valid ISBNs first
|
||||||
|
|
||||||
|
## Plugin Configuration
|
||||||
|
|
||||||
|
### WordPress Settings
|
||||||
|
|
||||||
|
The plugin uses these WordPress options:
|
||||||
|
|
||||||
|
- **`service_url`** - Custom API endpoint URL
|
||||||
|
- **`api_key`** - Custom API key (your credential would go here)
|
||||||
|
- **`typesense_api_key`** - TypeSense API key
|
||||||
|
- **`typesense_host`** - TypeSense host URL
|
||||||
|
- **`typesense_catalog`** - TypeSense catalog name
|
||||||
|
|
||||||
|
### Default Values
|
||||||
|
|
||||||
|
If no custom settings are provided:
|
||||||
|
- **URL:** `https://api.supafolio.com/v2/`
|
||||||
|
- **API Key:** `9819864f6ff0e8a5a097c99224cfd18a`
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
- API key is sent in HTTP headers (more secure than URL parameters)
|
||||||
|
- Plugin implements caching to reduce API calls
|
||||||
|
- Supports both HTTP and HTTPS protocols
|
||||||
|
- Custom service URLs can be configured for private deployments
|
||||||
|
|
||||||
|
## Alternative: TypeSense API
|
||||||
|
|
||||||
|
If using TypeSense instead of Supafolio:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET "https://{typesense-host}/collections/{catalog}/documents/search" \
|
||||||
|
-H "x-typesense-api-key: $TYPESENSE_API_KEY" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
The Supapress plugin provides comprehensive access to book metadata APIs through two main systems:
|
||||||
|
|
||||||
|
1. **Supafolio API** (primary) - Full-featured book data service
|
||||||
|
2. **TypeSense API** (alternative) - Search-focused service
|
||||||
|
|
||||||
|
Your credential `$SUPAFOLIO_API_KEY` can be used with either system, depending on your WordPress plugin configuration.
|
||||||
|
|
||||||
|
The curl commands provided above should give you complete access to test and interact with the API endpoints used by the Supapress plugin.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Generated:** 2026-01-24
|
||||||
|
**Plugin Version:** 2.26.2
|
||||||
|
**Analysis Scope:** Supafolio API integration in Supapress WordPress plugin
|
||||||
668
typesense-api-complete.md
Normal file
668
typesense-api-complete.md
Normal file
@ -0,0 +1,668 @@
|
|||||||
|
# TypeSense API Complete Documentation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
TypeSense is an open-source, typo-tolerant search engine designed for fast, instant search experiences. Built from the ground up in C++, it offers millisecond response times with intelligent default behaviors for search-as-you-type experiences.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
- **Open Source**: Free to use and modify (besides infrastructure costs)
|
||||||
|
- **RAM-Based Indexing**: Entire dataset should fit in RAM for optimal performance
|
||||||
|
- **Typo Tolerance**: Built-in fuzzy matching and typo correction
|
||||||
|
- **Instant Search**: Millisecond response times for typical queries
|
||||||
|
- **Privacy-Friendly**: Does not collect usage analytics or personal data
|
||||||
|
- **No Record Limits**: Only constrained by available RAM (up to 24 TB)
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### API Key Authentication
|
||||||
|
TypeSense uses API key authentication for secure access control.
|
||||||
|
|
||||||
|
#### Method: Header-Based
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: {api_key}" \
|
||||||
|
"https://{host}/collections/{collection}/documents/search"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Configuration in Supapress Plugin
|
||||||
|
```php
|
||||||
|
function supapress_set_typesense_client() {
|
||||||
|
$apiKey = (string)get_option('typesense_api_key');
|
||||||
|
$host = (string)get_option('typesense_host');
|
||||||
|
|
||||||
|
$client = new Client([
|
||||||
|
'nodes' => [
|
||||||
|
[
|
||||||
|
'host' => $host,
|
||||||
|
'port' => '',
|
||||||
|
'protocol' => 'https'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'api_key' => $apiKey,
|
||||||
|
'connection_timeout_seconds' => 2
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $client;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Required Settings
|
||||||
|
- **`typesense_api_key`**: API authentication key
|
||||||
|
- **`typesense_host`**: TypeSense server URL (without protocol)
|
||||||
|
- **`typesense_catalog`**: Collection name for book data
|
||||||
|
|
||||||
|
#### Activation
|
||||||
|
```php
|
||||||
|
define('TYPESENSE_API', true); // Enable TypeSense in Supapress
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete API Endpoints Reference
|
||||||
|
|
||||||
|
### 1. Search Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `GET /collections/{collection}/documents/search`
|
||||||
|
|
||||||
|
**Purpose**: Primary search operation for finding documents based on text queries, filters, and faceting.
|
||||||
|
|
||||||
|
#### Complete Parameter Reference
|
||||||
|
|
||||||
|
##### Query Parameters
|
||||||
|
|
||||||
|
| Parameter | Required | Description | Default | Example |
|
||||||
|
|------------|----------|-------------|---------|---------|
|
||||||
|
| `q` | yes | The query text to search for | `"javascript programming"` |
|
||||||
|
| `query_by` | yes | Fields to search within | `"title,description"` |
|
||||||
|
| `prefix` | no | Enable prefix searching | `true` |
|
||||||
|
| `infix` | no | Enable infix search | `false` |
|
||||||
|
| `pre_segmented_query` | no | Handle query segmentation manually | `false` |
|
||||||
|
| `num_typos` | no | Max typographical errors tolerated | `2` |
|
||||||
|
| `min_len_1typo` | no | Min word length for 1 typo | `4` |
|
||||||
|
| `min_len_2typo` | no | Min word length for 2 typos | `7` |
|
||||||
|
| `drop_tokens_threshold` | no | Drop words if insufficient results | `1` |
|
||||||
|
| `typo_tokens_threshold` | no | Start typo correction after N results | `1` |
|
||||||
|
| `enable_typos_for_numerical_tokens` | no | Enable typos on numerical tokens | `true` |
|
||||||
|
| `enable_typos_for_alpha_numerical_tokens` | no | Enable typos on alphanumerical tokens | `true` |
|
||||||
|
| `synonym_num_typos` | no | Allow synonym resolution on typos | `0` |
|
||||||
|
| `split_join_tokens` | no | Treat space as typo | `fallback` |
|
||||||
|
| `drop_tokens_mode` | no | Direction of word dropping | `right_to_left` |
|
||||||
|
| `max_candidates` | no | Similar words considered for prefix/typo | `4` |
|
||||||
|
| `max_extra_prefix` | no | Max symbols before/after query | `4` |
|
||||||
|
| `max_extra_suffix` | no | Max symbols before/after query | `4` |
|
||||||
|
| `preset` | no | Preset configuration name | |
|
||||||
|
| `vector_query` | no | Vector search query | |
|
||||||
|
| `voice_query` | no | Base64 encoded speech | |
|
||||||
|
| `stopwords` | no | Comma-separated stopword sets | |
|
||||||
|
| `validate_field_names` | no | Validate field existence | `true` |
|
||||||
|
|
||||||
|
##### Filter Parameters
|
||||||
|
|
||||||
|
| Parameter | Description | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `filter_by` | Complex filtering expressions | `country: USA` |
|
||||||
|
| | | Exact match vs non-exact | `category := Shoe` (exact) vs `category: Shoe` (partial) |
|
||||||
|
| | | Multiple values | `country: [USA, UK]` |
|
||||||
|
| | | Negation | `author: != JK Rowling` |
|
||||||
|
| | | Numeric ranges | `price: [10..100]` |
|
||||||
|
| | | Multiple conditions | `price: >10 && category: Fiction` |
|
||||||
|
| | | OR conditions | `color: blue || category: shoe` |
|
||||||
|
| | | Array filtering | `genres: [Rock, Pop]` |
|
||||||
|
| | | Nested object filtering | `ingredients.{name:=cheese && concentration:<30}` |
|
||||||
|
| | | Prefix filtering | `company_name: Acm*` |
|
||||||
|
| `enable_lazy_filter` | no | Incremental filtering | `false` |
|
||||||
|
| `max_filter_by_candidates` | no | Similar words for fuzzy filter | `4` |
|
||||||
|
| `validate_field_names` | no | Validate filtered fields | `true` |
|
||||||
|
|
||||||
|
##### Ranking & Sorting Parameters
|
||||||
|
|
||||||
|
| Parameter | Description | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `sort_by` | Primary sorting control | `publicationDate:desc,title:asc` |
|
||||||
|
| | | Multiple fields with tie-breaking | `price:desc,popularity:asc,rating:desc` |
|
||||||
|
| | | Special `_text_match` field | `_text_match:desc` |
|
||||||
|
| | | Conditional sorting | `_eval(in_stock:true):desc` |
|
||||||
|
| `query_by_weights` | Field importance weighting | `title:2,description:1,author:1` |
|
||||||
|
| `text_match_type` | Text match scoring | `max_score` (default) |
|
||||||
|
| `prioritize_exact_match` | Exact match priority | `true` |
|
||||||
|
| `prioritize_token_position` | Word position priority | `false` |
|
||||||
|
| `prioritize_num_matching_fields` | Multiple field match priority | `true` |
|
||||||
|
|
||||||
|
##### Pagination Parameters
|
||||||
|
|
||||||
|
| Parameter | Description | Default |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `page` | Page number | `1` |
|
||||||
|
| `per_page` | Results per page (max 250) | `10` |
|
||||||
|
| `offset` | Starting point | `0` |
|
||||||
|
| `limit` | Maximum hits | No limit |
|
||||||
|
|
||||||
|
##### Faceting Parameters
|
||||||
|
|
||||||
|
| Parameter | Description | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `facet_by` | Fields to facet on | `category,brand,price_range` |
|
||||||
|
| `facet_strategy` | Facet calculation method | `exhaustive` |
|
||||||
|
| `max_facet_values` | Max facet values returned | `10` |
|
||||||
|
| `facet_query` | Filter facet values | `facet_query=category:shoe` |
|
||||||
|
| `facet_query_num_typos` | Facet query fuzziness | `2` |
|
||||||
|
| `facet_return_parent` | Return parent objects | `color.name` |
|
||||||
|
| `facet_sample_percent` | Sampling percentage | `100` |
|
||||||
|
| `facet_sample_threshold` | Min hits for sampling | `0` |
|
||||||
|
|
||||||
|
##### Grouping Parameters
|
||||||
|
|
||||||
|
| Parameter | Description | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `group_by` | Field to group by | `category,company_name` |
|
||||||
|
| `group_limit` | Max hits per group | `3` |
|
||||||
|
| `group_missing_values` | Include null values in groups | `true` |
|
||||||
|
|
||||||
|
##### Results Parameters
|
||||||
|
|
||||||
|
| Parameter | Description | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `include_fields` | Fields to include | `title,author,price` |
|
||||||
|
| `exclude_fields` | Fields to exclude | `search_time_ms,out_of` |
|
||||||
|
| `highlight_fields` | Fields to highlight | `title,description` |
|
||||||
|
| `highlight_full_fields` | Full field highlighting | `title,description` |
|
||||||
|
| `highlight_affix_num_tokens` | Tokens around highlight | `4` |
|
||||||
|
| `highlight_start_tag` | Highlight start tag | `<mark>` |
|
||||||
|
| `highlight_end_tag` | Highlight end tag | `</mark>` |
|
||||||
|
| `snippet_threshold` | Full field highlight length | `30` |
|
||||||
|
| `limit_hits` | Maximum hits | `200` |
|
||||||
|
| `search_cutoff_ms` | Search timeout | No cutoff |
|
||||||
|
| `exhaustive_search` | Consider all variations | `false` |
|
||||||
|
| `use_cache` | Enable server caching | `false` |
|
||||||
|
| `cache_ttl` | Cache duration in seconds | `60` |
|
||||||
|
|
||||||
|
##### Curation Parameters
|
||||||
|
|
||||||
|
| Parameter | Description |
|
||||||
|
|------------|-------------|
|
||||||
|
| `pinned_hits` | Promote specific hits | `123:1,456:5` |
|
||||||
|
| `hidden_hits` | Hide specific hits | `123,456` |
|
||||||
|
| `enable_overrides` | Enable curation rules | `true` |
|
||||||
|
| `override_tags` | Trigger specific rules | `featured,new_release` |
|
||||||
|
|
||||||
|
#### Sample Request
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books/documents/search?q=javascript&query_by=title,description&sort_by=publicationDate:desc&facet_by=category,author&per_page=20"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sample Response
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hits": [
|
||||||
|
{
|
||||||
|
"document": {
|
||||||
|
"id": "421",
|
||||||
|
"title": "JavaScript: The Good Parts",
|
||||||
|
"authors": ["Douglas Crockford"],
|
||||||
|
"publicationDate": 1640995200,
|
||||||
|
"categories": ["Programming", "Web Development"],
|
||||||
|
"prices": {
|
||||||
|
"USD": {"amount": 29.99, "discount": 5.00},
|
||||||
|
"GBP": {"amount": 24.99, "discount": 4.00}
|
||||||
|
},
|
||||||
|
"image": "https://example.com/covers/js-good-parts.jpg"
|
||||||
|
},
|
||||||
|
"highlights": {
|
||||||
|
"title": [
|
||||||
|
{"value": "<mark>JavaScript</mark>", "matched_tokens": ["javascript"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"facet_counts": [
|
||||||
|
{
|
||||||
|
"field_name": "categories",
|
||||||
|
"counts": [
|
||||||
|
{"value": "Programming", "count": 156},
|
||||||
|
{"value": "Web Development", "count": 89},
|
||||||
|
{"value": "Fiction", "count": 234}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"found": 1250,
|
||||||
|
"out_of": 5000,
|
||||||
|
"page": 1,
|
||||||
|
"request_params": {
|
||||||
|
"per_page": 20,
|
||||||
|
"q": "javascript"
|
||||||
|
},
|
||||||
|
"search_cutoff_ms": true,
|
||||||
|
"search_time_ms": 12
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Documents Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `POST /collections/{collection}/documents`
|
||||||
|
|
||||||
|
#### Indexing Single Document
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"id": "123", "title": "New Book", "author": "Author Name"}' \
|
||||||
|
"https://typesense.example.com/collections/books/documents"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Indexing Multiple Documents
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
-H "Content-Type: application/jsonl" \
|
||||||
|
--data-binary @books.jsonl \
|
||||||
|
"https://typesense.example.com/collections/books/documents/import"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Retrieving Single Document
|
||||||
|
**Endpoint**: `GET /collections/{collection}/documents/{id}`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books/documents/123"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Updating Document
|
||||||
|
**Endpoint**: `PATCH /collections/{collection}/documents/{id}`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X PATCH \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"price": 19.99}' \
|
||||||
|
"https://typesense.example.com/collections/books/documents/123"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deleting Document
|
||||||
|
**Endpoint**: `DELETE /collections/{collection}/documents/{id}`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books/documents/123"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Collections Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `POST /collections`
|
||||||
|
|
||||||
|
#### Create Collection
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"name": "books",
|
||||||
|
"fields": [
|
||||||
|
{"name": "title", "type": "string", "facet": true},
|
||||||
|
{"name": "author", "type": "string", "facet": false},
|
||||||
|
{"name": "publicationDate", "type": "int64", "facet": false},
|
||||||
|
{"name": "price", "type": "float", "facet": true},
|
||||||
|
{"name": "categories", "type": "string[]", "facet": true, "optional": false}
|
||||||
|
],
|
||||||
|
"default_sorting_field": "publicationDate",
|
||||||
|
"token_separators": " "
|
||||||
|
}' \
|
||||||
|
"https://typesense.example.com/collections"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Retrieve Collection Schema
|
||||||
|
**Endpoint**: `GET /collections/{collection}`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Delete Collection
|
||||||
|
**Endpoint**: `DELETE /collections/{collection}`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Vector Search Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `POST /collections/{collection}/documents/search`
|
||||||
|
|
||||||
|
#### Vector Query
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"q": "*",
|
||||||
|
"vector_query": {
|
||||||
|
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
|
||||||
|
"k": 10
|
||||||
|
},
|
||||||
|
"query_by": "title"
|
||||||
|
}' \
|
||||||
|
"https://typesense.example.com/collections/books/documents/search"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Geo Search Endpoint
|
||||||
|
|
||||||
|
**Endpoint**: `GET /collections/{collection}/documents/search`
|
||||||
|
|
||||||
|
#### Location-based Search
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books/documents/search?q=*&filter_by=location:(48.853,2.344,5.1)&sort_by=location_field_name(48.853,2.344,5.1):asc"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Geo-filtered Search
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/collections/books/documents/search?q=coffee&filter_by=location:(48.853,2.344,5.1,10km)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. API Keys Endpoint
|
||||||
|
|
||||||
|
#### Generate Scoped Search Key
|
||||||
|
**Endpoint**: `POST /keys`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: master_key" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"description": "Public search key for website",
|
||||||
|
"actions": ["documents:search"],
|
||||||
|
"collections": ["books"],
|
||||||
|
"expires_at": 1735689599
|
||||||
|
}' \
|
||||||
|
"https://typesense.example.com/keys"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### List API Keys
|
||||||
|
**Endpoint**: `GET /keys`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -H "X-TYPESENSE-API-KEY: master_key" \
|
||||||
|
"https://typesense.example.com/keys"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Delete API Key
|
||||||
|
**Endpoint**: `DELETE /keys/{id}`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE \
|
||||||
|
-H "X-TYPESENSE-API-KEY: master_key" \
|
||||||
|
"https://typesense.example.com/keys/123"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Cluster Operations
|
||||||
|
|
||||||
|
#### Create Snapshot
|
||||||
|
**Endpoint**: `POST /operations/snapshot`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/operations/snapshot"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Compact Database
|
||||||
|
**Endpoint**: `POST /operations/db/compact`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/operations/db/compact"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Clear Cache
|
||||||
|
**Endpoint**: `POST /operations/cache/clear`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST \
|
||||||
|
-H "X-TYPESENSE-API-KEY: xyz" \
|
||||||
|
"https://typesense.example.com/operations/cache/clear"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Schema for Book Collections
|
||||||
|
|
||||||
|
### Core Fields
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "string (unique identifier)",
|
||||||
|
"title": "string (full title)",
|
||||||
|
"subtitle": "string (subtitle/edition)",
|
||||||
|
"description": "string (full description)",
|
||||||
|
"summary": "string (brief summary)",
|
||||||
|
"authors": ["string array (author names)"],
|
||||||
|
"publicationDate": "timestamp (Unix epoch)",
|
||||||
|
"saleDate": "timestamp (Unix epoch)",
|
||||||
|
"publisher": "string (publisher name)",
|
||||||
|
"imprint": "string (imprint name)",
|
||||||
|
"isbn13": "string (ISBN-13)",
|
||||||
|
"isbn10": "string (ISBN-10)",
|
||||||
|
"pages": "integer (page count)",
|
||||||
|
"language": "string (language code)",
|
||||||
|
"categories": ["string array (subject categories)"],
|
||||||
|
"collections": ["string array (series collections)"],
|
||||||
|
"formats": [
|
||||||
|
{
|
||||||
|
"format": {"name": "string", "format_id": "number"},
|
||||||
|
"isbn": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prices": {
|
||||||
|
"USD": {"amount": "number", "discount": "number"},
|
||||||
|
"GBP": {"amount": "number", "discount": "number"},
|
||||||
|
"CAD": {"amount": "number", "discount": "number"},
|
||||||
|
"EUR": {"amount": "number", "discount": "number"}
|
||||||
|
},
|
||||||
|
"image": "url (cover image URL)",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"asset": {
|
||||||
|
"type": "string",
|
||||||
|
"sub_type": "string",
|
||||||
|
"path": "url",
|
||||||
|
"width": "number",
|
||||||
|
"height": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trim": {
|
||||||
|
"width": "number",
|
||||||
|
"height": "number",
|
||||||
|
"depth": "number",
|
||||||
|
"unit": "string"
|
||||||
|
},
|
||||||
|
"weight": {
|
||||||
|
"weight": "number",
|
||||||
|
"weight_unit": "string"
|
||||||
|
},
|
||||||
|
"edition": "string",
|
||||||
|
"awards": [
|
||||||
|
{
|
||||||
|
"award": {"name": "string", "id": "number"}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reviews": [
|
||||||
|
{
|
||||||
|
"review": {"description": "string"}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"retailers": [
|
||||||
|
{
|
||||||
|
"label": "string",
|
||||||
|
"path": "string",
|
||||||
|
"seo": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Faceted Fields Configuration
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "categories",
|
||||||
|
"type": "string[]",
|
||||||
|
"facet": true,
|
||||||
|
"optional": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "author",
|
||||||
|
"type": "string",
|
||||||
|
"facet": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "publicationDate",
|
||||||
|
"type": "int64",
|
||||||
|
"facet": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "price",
|
||||||
|
"type": "float",
|
||||||
|
"facet": true,
|
||||||
|
"optional": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Typo Tolerance
|
||||||
|
- **Damerau-Levenshtein distance** for calculating edit distance
|
||||||
|
- **Configurable tolerance levels** (0, 1, 2 typos)
|
||||||
|
- **Prefix/Infix search** for autocomplete scenarios
|
||||||
|
- **Split join tokens** for space-as-typo handling
|
||||||
|
|
||||||
|
### Faceting Capabilities
|
||||||
|
- **Exhaustive vs Top Values** strategies for performance
|
||||||
|
- **Numerical range faceting** with custom labels
|
||||||
|
- **Nested object faceting** for complex data structures
|
||||||
|
- **Facet query filtering** for drill-down scenarios
|
||||||
|
|
||||||
|
### Sorting Options
|
||||||
|
- **Multi-field sorting** with tie-breaking
|
||||||
|
- **Text match score** sorting by relevance
|
||||||
|
- **Conditional expressions** for dynamic sorting
|
||||||
|
- **Decay functions** for time-based relevance
|
||||||
|
- **Random sorting** with seed control
|
||||||
|
|
||||||
|
### Caching & Performance
|
||||||
|
- **Query result caching** with TTL control
|
||||||
|
- **RAM-based indexing** for instant search
|
||||||
|
- **Connection pooling** for high throughput
|
||||||
|
- **Lazy filtering** for large datasets
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Common Error Responses
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "No such collection found.",
|
||||||
|
"code": 404
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Bad request.",
|
||||||
|
"code": 400
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Codes Reference
|
||||||
|
|
||||||
|
| Code | Description | Solution |
|
||||||
|
|-------|-------------|----------|
|
||||||
|
| 400 | Bad Request | Check JSON syntax, required parameters |
|
||||||
|
| 401 | Unauthorized | Verify API key in headers |
|
||||||
|
| 404 | Not Found | Check collection/document existence |
|
||||||
|
| 409 | Conflict | Document ID already exists |
|
||||||
|
| 422 | Unprocessable | Validate field types/values |
|
||||||
|
| 429 | Too Many Requests | Implement rate limiting |
|
||||||
|
| 500 | Internal Error | Contact TypeSense support |
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
### Indexing Strategy
|
||||||
|
- **RAM allocation**: Plan for 2x dataset size
|
||||||
|
- **Field selection**: Search only relevant fields
|
||||||
|
- **Schema optimization**: Enable sorting on frequently filtered fields
|
||||||
|
- **Tokenizer configuration**: Custom separators for content
|
||||||
|
|
||||||
|
### Query Optimization
|
||||||
|
- **Prefix queries**: Use `prefix=true` for autocomplete
|
||||||
|
- **Field weighting**: Prioritize important fields
|
||||||
|
- **Filter early**: Apply `filter_by` before full text search
|
||||||
|
- **Limit results**: Use `per_page` appropriately
|
||||||
|
|
||||||
|
### Caching Strategy
|
||||||
|
- **Server-side**: Enable `use_cache=true` for repeated queries
|
||||||
|
- **Client-side**: Implement application-level caching
|
||||||
|
- **TTL management**: Set appropriate `cache_ttl` values
|
||||||
|
|
||||||
|
## Integration Examples
|
||||||
|
|
||||||
|
### Basic Search Implementation
|
||||||
|
```javascript
|
||||||
|
const client = new TypesenseClient({
|
||||||
|
nodes: [{
|
||||||
|
host: 'typesense.example.com',
|
||||||
|
port: '443',
|
||||||
|
protocol: 'https'
|
||||||
|
}],
|
||||||
|
apiKey: 'xyz',
|
||||||
|
connectionTimeoutSeconds: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
const searchResults = await client.collections('books')
|
||||||
|
.documents()
|
||||||
|
.search({
|
||||||
|
q: 'javascript programming',
|
||||||
|
query_by: 'title,description',
|
||||||
|
facet_by: 'categories,author',
|
||||||
|
sort_by: 'publicationDate:desc',
|
||||||
|
per_page: 20
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Faceted Search with Filters
|
||||||
|
```javascript
|
||||||
|
const results = await client.collections('books')
|
||||||
|
.documents()
|
||||||
|
.search({
|
||||||
|
q: '*',
|
||||||
|
filter_by: 'categories:[Programming,Web Development] && price:[20..50]',
|
||||||
|
facet_by: 'categories,author,publicationYear',
|
||||||
|
max_facet_values: 15,
|
||||||
|
sort_by: 'price:asc,title:asc'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Auto-complete Implementation
|
||||||
|
```javascript
|
||||||
|
const suggestions = await client.collections('books')
|
||||||
|
.documents()
|
||||||
|
.search({
|
||||||
|
q: userQuery,
|
||||||
|
query_by: 'title,author',
|
||||||
|
prefix: true,
|
||||||
|
per_page: 8,
|
||||||
|
highlight_fields: 'title',
|
||||||
|
highlight_affix_num_tokens: 2
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Generated**: 2026-01-24
|
||||||
|
**TypeSense Version**: v29.0
|
||||||
|
**Supapress Plugin**: v2.26.2
|
||||||
Loading…
x
Reference in New Issue
Block a user