Skip to main content

Developer Portal

The Developer Portal is where you manage your external service credentials (Credentials Vault), generate platform API keys, and monitor usage.

Credentials Vault

Store and manage API keys for external services like OpenAI, Stripe, Cloudflare, etc.

Why a Vault?

Without centralized credential management:
  • Keys scattered across .env files, Vercel, password managers
  • No visibility into which keys are used where
  • No expiration tracking or rotation reminders
  • Risk of keys in git history or logs
The Credentials Vault solves this:
  • Encrypted storage - Keys encrypted at rest with Supabase Vault
  • Key hints only - Full key never retrievable after save
  • Environment separation - Dev, staging, production isolated
  • Usage tracking - See when credentials were last used
  • Expiration alerts - Get notified before keys expire

Supported Providers

52 providers across 11 categories:
CategoryProviders
AIOpenAI, Anthropic, Google AI, Replicate, Hugging Face, Groq, Together AI, Perplexity, Mistral, Cohere
PaymentsStripe, PayPal, Square, Wise
EmailResend, SendGrid, Mailchimp, Postmark, AWS SES
CommunicationsTwilio, Vonage
StorageCloudflare R2, AWS S3, Supabase Storage, Cloudinary, Uploadthing
DatabaseSupabase, PlanetScale, Neon, Turso, Upstash
InfrastructureVercel, Cloudflare, AWS, Google Cloud, Fly.io, Railway, Render
DevelopmentGitHub, GitLab, Linear, Figma
ProductivityNotion, Slack, Airtable, Google Workspace
AnalyticsMixpanel, Amplitude, PostHog, Segment
MonitoringSentry, Datadog, LogSnag
EcommerceShopify, Stripe
AffiliateImpact, Viator, Amazon Associates
ScrapingApify, Browserless, ScrapingBee

Adding a Credential

// POST /api/credentials
{
  "provider_id": "uuid-of-openai",
  "name": "Production OpenAI",
  "environment": "production",
  "credential": "sk-proj-xxxxxxxxxxxxx",
  "scopes": ["chat", "embeddings", "images"]
}
Response:
{
  "id": "uuid",
  "name": "Production OpenAI",
  "environment": "production",
  "key_hint": "...xxxxx",
  "provider": {
    "name": "OpenAI",
    "icon_url": "..."
  }
}
The full credential is encrypted immediately. You cannot retrieve it later—only the last 6 characters (hint) are stored in plaintext.

Using Credentials

Credentials are used by:
  1. Jarvis - AI inference calls
  2. Automations - Scheduled workflows
  3. Edge Functions - Server-side API calls
// Server-side: Get decrypted credential
import { getCredential } from '@trendingsociety/db/credentials';

const openaiKey = await getCredential({
  tenantId: 'xxx',
  providerSlug: 'openai',
  environment: 'production'
});

// Use with OpenAI SDK
const openai = new OpenAI({ apiKey: openaiKey });

Platform API Keys

Generate API keys to access Trending Engine APIs programmatically.

Key Types

EnvironmentPrefixUse Case
Sandboxts_test_Development, testing
Productionts_live_Live applications

Scopes

API keys can be scoped to specific operations:
ScopeAccess
content:readRead articles, sites
content:writeCreate, update, delete content
jarvis:invokeCall Jarvis API
analytics:readRead analytics data
users:readRead user data
users:writeManage users
billing:readView billing info

Creating an API Key

// POST /api/api-keys
{
  "name": "Mobile App - Production",
  "environment": "production",
  "scopes": ["content:read", "jarvis:invoke"],
  "rate_limit_per_minute": 100,
  "expires_at": "2026-01-01T00:00:00Z"  // Optional
}
Response:
{
  "id": "uuid",
  "name": "Mobile App - Production",
  "key": "ts_live_xxxxxxxxxxxxxxxxxxxxxxxx",
  "key_prefix": "ts_live_xxx",
  "scopes": ["content:read", "jarvis:invoke"],
  "rate_limit_per_minute": 100
}
The full API key is shown only once at creation. Copy it immediately—it cannot be retrieved later.

Using Your API Key

Include in the Authorization header:
curl https://api.trendingsociety.com/v1/content \
  -H "Authorization: Bearer ts_live_xxxxxxxx"
Or with SDK:
import { TrendingEngine } from '@trendingsociety/sdk';

const client = new TrendingEngine({
  apiKey: process.env.TRENDING_ENGINE_API_KEY
});

const articles = await client.content.list({ limit: 10 });

Usage & Billing

Track API usage and manage quotas.

Usage Dashboard

View usage by:
  • Time period - Daily, weekly, monthly
  • API product - Content, Jarvis, Analytics, etc.
  • Endpoint - Specific routes
  • Status - Success vs. errors

Quotas & Limits

Each plan includes base quotas:
PlanContent APIJarvis APIAnalytics API
Free100/mo10K tokens/mo1K/mo
Pro5K/mo500K tokens/mo50K/mo
Business50K/mo5M tokens/mo500K/mo
EnterpriseUnlimitedUnlimitedUnlimited

Overage Pricing

When you exceed quotas, overage rates apply:
ProductOverage Rate
Content API$0.05/request
Jarvis API$0.00001/token
Analytics API$0.001/request
Distribution API$0.02/request
UCI Identity API$0.10/request

Usage Alerts

Configure alerts at threshold levels:
// POST /api/usage-alerts
{
  "product_id": "uuid-of-jarvis",
  "threshold_percent": 80,
  "notification_type": "email",
  "notification_target": "[email protected]"
}
You’ll receive notifications at 80%, 90%, and 100% of quota.

Webhooks

Receive real-time notifications when events occur.

Creating a Webhook

// POST /api/webhooks
{
  "url": "https://your-app.com/webhooks/trending",
  "events": [
    "content.published",
    "user.joined",
    "api_key.created"
  ]
}
Response:
{
  "id": "uuid",
  "url": "https://your-app.com/webhooks/trending",
  "events": ["content.published", "user.joined", "api_key.created"],
  "secret": "whsec_xxxxxxxxxxxxxxxx"
}

Verifying Webhooks

All webhooks are signed with HMAC-SHA256:
import { createHmac } from 'crypto';

function verifyWebhook(payload: string, signature: string, secret: string) {
  const expected = createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return `sha256=${expected}` === signature;
}

// In your handler
app.post('/webhooks/trending', (req, res) => {
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    req.headers['x-trending-signature'],
    process.env.WEBHOOK_SECRET
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process webhook...
});

Webhook Payload

{
  "id": "evt_xxxxx",
  "type": "content.published",
  "created_at": "2025-01-15T10:30:00Z",
  "data": {
    "article_id": "uuid",
    "title": "10 AI Trends for 2025",
    "site_id": "uuid",
    "published_at": "2025-01-15T10:30:00Z"
  }
}

Available Events

EventDescription
tenant.createdNew tenant signed up
tenant.updatedTenant settings changed
content.publishedArticle published
content.updatedArticle modified
site.createdNew site added
site.deletedSite removed
user.invitedTeam invite sent
user.joinedUser accepted invite
api_key.createdNew API key generated
api_key.revokedAPI key revoked

Retry Policy

Failed deliveries are retried with exponential backoff:
  • Attempt 1: Immediate
  • Attempt 2: 1 minute
  • Attempt 3: 5 minutes
  • Attempt 4: 30 minutes
  • Attempt 5: 2 hours
After 5 failures, the webhook is paused and you’re notified.