SaaS Store API
Programmatic access to search tools, get recommendations, and receive real-time webhooks.
v1RESTJSON
Authentication
All API requests require an API key. Pass it via the Authorization header:
Authorization: Bearer sk_live_your_api_key_here # Or via X-API-Key header: X-API-Key: sk_live_your_api_key_here
Get your API key from the Dashboard.
Rate Limiting
Default rate limit is 100 requests per minute per API key. Rate limit headers are included in every response:
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 2024-01-01T00:01:00Z
Webhook Verification
Each webhook delivery includes a X-Webhook-Signature header. Verify it using HMAC-SHA256:
const crypto = require('crypto');
function verify(payload, signature, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(payload).digest('hex');
return expected === signature;
}Endpoints
GET
/api/v1/toolsSearch and list toolsParameters
| Name | Type | Description |
|---|---|---|
q | string | Search query (name, tagline, description) |
category | string | Filter by category slug |
pricing | string | Filter by pricing model (free, freemium, paid, etc.) |
sort | string | Sort: newest (default), popular, name, oldest |
page | number | Page number (default: 1) |
limit | number | Results per page (1-50, default: 20) |
slug | string | Get single tool by slug |
Example
curl -H "Authorization: Bearer sk_live_..." \ "https://your-domain.com/api/v1/tools?q=analytics&limit=5"
Response
{
"data": [
{
"id": 1,
"name": "ToolName",
"slug": "toolname",
"tagline": "Short description",
"logo_url": "...",
"pricing_model": "freemium",
"views": 1234,
"tags": ["analytics", "data"],
"created_at": "2024-01-01T00:00:00Z",
"tool_categories": [...]
}
],
"meta": { "page": 1, "limit": 5, "total": 42, "total_pages": 9 }
}GET
/api/v1/categoriesList all categories with tool countsExample
curl -H "Authorization: Bearer sk_live_..." \ "https://your-domain.com/api/v1/categories"
Response
{
"data": [
{ "id": 1, "name": "Analytics", "slug": "analytics", "tool_count": 15 }
]
}GET
/api/v1/statsPlatform-wide statisticsExample
curl -H "Authorization: Bearer sk_live_..." \ "https://your-domain.com/api/v1/stats"
Response
{
"data": {
"total_tools": 250,
"total_reviews": 1200,
"total_users": 500,
"total_categories": 12,
"avg_rating": 4.2,
"new_tools_this_week": 8,
"new_reviews_this_week": 45
}
}GET
/api/v1/recommendationsPersonalized tool recommendations (based on API key owner's activity)Parameters
| Name | Type | Description |
|---|---|---|
limit | number | Number of results (1-50, default: 12) |
Example
curl -H "Authorization: Bearer sk_live_..." \ "https://your-domain.com/api/v1/recommendations?limit=6"
Response
{
"data": [
{
"id": 5,
"name": "RecTool",
"slug": "rectool",
"rec_score": 85.5,
"rec_reasons": ["category_match", "highly_rated"]
}
]
}GET
/api/v1/webhooksList your registered webhooksExample
curl -H "Authorization: Bearer sk_live_..." \ "https://your-domain.com/api/v1/webhooks"
Response
{
"data": {
"webhooks": [...],
"available_events": [
{ "value": "tool.created", "label": "Tool Created" },
...
]
}
}POST
/api/v1/webhooksRegister a new webhook endpoint (requires write scope)Parameters
| Name | Type | Description |
|---|---|---|
url | string | Webhook URL (HTTPS) |
events | string[] | Events to subscribe to |
description | string | Optional description |
Example
curl -X POST -H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://your.app/webhook","events":["tool.created","review.created"]}' \
"https://your-domain.com/api/v1/webhooks"Response
{
"data": {
"id": 1,
"url": "https://your.app/webhook",
"events": ["tool.created", "review.created"],
"secret": "whsec_abc123..."
}
}Error Codes
| Status | Code | Description |
|---|---|---|
| 401 | missing_api_key | No API key provided |
| 401 | invalid_api_key | API key not found |
| 403 | key_disabled | API key has been disabled |
| 403 | key_expired | API key has expired |
| 403 | insufficient_scope | Key lacks required scope |
| 429 | rate_limit_exceeded | Too many requests |
| 404 | tool_not_found | Tool not found |
| 500 | query_error | Internal server error |