Sign up free
API

API Reference

The Bloomberry API is a REST API that powers the Bloomberry web app and enables programmatic access to all core features. All endpoints return JSON.

Base URL

Base URL
https://scintillating-clarity-production-ef70.up.railway.app

The base URL is set via the NEXT_PUBLIC_BACKEND_URL environment variable. See Environment Variables for setup.

Authentication

All authenticated endpoints require a Clerk session token in the Authorization header.

Authentication header
Authorization: Bearer <clerk-session-token>

The Bloomberry frontend obtains this token automatically via Clerk's getToken() helper. For direct API access, obtain a session token from your Clerk dashboard.

Writer API

MethodEndpointDescriptionAuth
POST/api/writer/generateGenerate content from a concept
POST/api/writer/generate-streamStream content generation (SSE)
POST/api/writer/previewPreview generation without saving
POST/api/writer/parse-intentParse intent from rough concept
POST/api/writer/extract-textExtract text from uploaded file

POST /api/writer/generate

Generates content from a concept. Supports all 6 output formats.

Request body
{
  "concept": "Why most founders under-invest in personal brand",
  "formats": ["linkedin", "x"],
  "style": "natural",
  "sessionId": "sess_abc123"
}
Response
{
  "sessionId": "sess_abc123",
  "outputs": {
    "linkedin": {
      "content": "Most founders spend years...",
      "wordCount": 280,
      "estimatedReadTime": "1 min"
    },
    "x": {
      "content": "Thread: Why founders under-invest in personal brand

1/ ...",
      "tweets": ["Why founders...", "Most believe..."]
    }
  },
  "tokensUsed": 1240,
  "model": "gemini-1.5-pro"
}

POST /api/writer/generate-stream

Streams generation output using Server-Sent Events (SSE). Supported by both authenticated and unauthenticated users (unauthenticated users receive 1 free generation).

Example SSE connection
"color:#79c0ff">curl -X POST https://scintillating-clarity-production-ef70.up.railway.app/api/writer/generate-stream \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"concept": "Your concept here", "formats": ["linkedin"]}' \
  --no-buffer

Sessions API

MethodEndpointDescriptionAuth
GET/api/writer/sessionsList all writer sessions
POST/api/writer/sessionsCreate a new session
GET/api/writer/sessions/:idGet a specific session
PUT/api/writer/sessions/:idUpdate session content
DELETE/api/writer/sessions/:idDelete a session

Knowledge API

MethodEndpointDescriptionAuth
GET/api/knowledgeList all knowledge base entries
POST/api/knowledgeAdd a knowledge base entry
DELETE/api/knowledge/:idDelete a knowledge entry
POST/api/knowledge/matchSemantic match entries to a prompt
POST/api/knowledge/extractAuto-extract entries from text

Brand Kit API

MethodEndpointDescriptionAuth
GET/api/brand-kitGet brand kit for current user
PUT/api/brand-kitUpdate brand kit
POST/api/brand-kit/upload-logoUpload logo file

Scheduler API

MethodEndpointDescriptionAuth
GET/api/scheduler/postsList scheduled posts
POST/api/scheduler/postsSchedule a post
PUT/api/scheduler/posts/:idUpdate scheduled post
DELETE/api/scheduler/posts/:idCancel scheduled post
GET/api/scheduler/queueGet posting queue

Billing API

MethodEndpointDescriptionAuth
POST/api/billing/checkoutCreate Stripe checkout session
POST/api/billing/portalOpen Stripe customer portal
POST/api/billing/webhookStripe webhook receiver
GET/api/billing/usageGet current usage stats

Error handling

All errors follow a consistent format:

Error response
{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Monthly chat limit reached. Upgrade to Pro for unlimited chats.",
    "statusCode": 429
  }
}
StatusCodeMeaning
400INVALID_REQUESTMalformed request body or missing required fields
401UNAUTHORIZEDMissing or invalid authentication token
403FORBIDDENAuthenticated but insufficient permissions
429QUOTA_EXCEEDEDMonthly usage limit reached
429RATE_LIMITEDToo many requests in a short period
500INTERNAL_ERRORServer error — reported automatically
Edit this page on GitHub