SaaS Store

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 tools

Parameters

NameTypeDescription
qstringSearch query (name, tagline, description)
categorystringFilter by category slug
pricingstringFilter by pricing model (free, freemium, paid, etc.)
sortstringSort: newest (default), popular, name, oldest
pagenumberPage number (default: 1)
limitnumberResults per page (1-50, default: 20)
slugstringGet 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 counts

Example

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 statistics

Example

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

NameTypeDescription
limitnumberNumber 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 webhooks

Example

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

NameTypeDescription
urlstringWebhook URL (HTTPS)
eventsstring[]Events to subscribe to
descriptionstringOptional 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

StatusCodeDescription
401missing_api_keyNo API key provided
401invalid_api_keyAPI key not found
403key_disabledAPI key has been disabled
403key_expiredAPI key has expired
403insufficient_scopeKey lacks required scope
429rate_limit_exceededToo many requests
404tool_not_foundTool not found
500query_errorInternal server error