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