Functions API (OAuth & Publish)
Quick links: Frontend β’ Backend β’ Error Handling
Backendβ
All Functions are deployed under your project region, e.g. https://<region>-<project>.cloudfunctions.net. Orchestrators and provider publish functions are invoked via Cloud Tasks using function URLs built from names (see apps/functions/tasks.js).
Common headers:
Authorization: Bearer <Firebase ID token>for user-scoped endpoints.
Endpoints (examples):
-
Facebook
GET /fbAuthStart?redirect=1&return_to=<url>β redirects to OAuth (requiresAuthorization: Bearer <idToken>)GET /fbAuthCallback?code=...&state=...β persists tokens, selects managed Page when availablePOST /publishFacebookBody:{ userId, postSubmissionId, request }withrequest.post.content.text
-
Instagram
GET /igAuthStart?redirect=1&return_to=<url>(requires id token)GET /igAuthCallback?code=...&state=...POST /publishInstagramBody:{ userId, postSubmissionId, request }whererequest.post.content.mediaUrls[0]is an image URL; optionaltextas caption
-
Threads
GET /thAuthStart?redirect=1&return_to=<url>(requires id token)GET /thAuthCallback?code=...&state=...POST /publishThreadsBody:{ userId, postSubmissionId, request }withrequest.post.content.text
-
X (Twitter)
GET /xAuthStart?redirect=1&return_to=<url>(OAuth2 PKCE; requires id token)GET /xAuthCallback?code=...&state=...GET /xAuth1Start?redirect=1&sid=<sid>&return_to=<url>(optional chained OAuth1; no header ifsidprovided; otherwise requires id token)GET /xAuth1Callback?oauth_token=...&oauth_verifier=...POST /publishXBody:{ userId, postSubmissionId, request }withrequest.post.content.text, optionalrequest.post.content.mediaIds[]ormediaUrls[]
-
TikTok
GET /ttAuthStart?redirect=1&return_to=<url>&desktop=1(requires id token)GET /ttAuthCallback?code=...&state=...POST /ttRefreshNow(refresh token)- Scheduler:
ttRefreshSweep POST /publishTiktokBody:{ userId, postSubmissionId, request }whererequest.post.content.textis required and eithervideoUrlor one ofimageUrls[]|mediaUrls[]is provided; we rehost media when possible and poll status to resolveshareUrl/postId.
-
YouTube
GET /ytAuthStart?redirect=1&return_to=<url>(requires id token)GET /ytAuthCallback?code=...&state=...POST /ytRefreshNow- Scheduler:
ytRefreshSweep
See apps/functions/index.js for exports and apps/functions/integrations/* for providers.
Orchestrators and Utilitiesβ
- Orchestrators
POST /publishOrchestrator(internal fanβout via Cloud Tasks): Body{ userId, postSubmissionId, request }POST /repostOrchestrator(internal; used by organic repost flow): Body{ userId, postId }
- Internal publish entry
POST /publishPost(requires Firebase ID token): Body{ post, scheduledTime? }β creates a submission and orchestrates
- Media proxy
GET|HEAD /media/{id}[.{ext}]streams from Firebase Storage via signed token
- Webhooks
POST /stripeWebhookStripe events (checkout.session.completed,customer.subscription.*,invoice.*)GET|POST /metaWebhookMeta verification (GET) and webhook receiver (POST)
Related frontend: see Frontend
Error Handlingβ
The API uses a comprehensive error handling system with structured responses and detailed logging.
Error Response Formatβ
{
"error": {
"code": "validation_error",
"message": "Request validation failed",
"timestamp": "2025-08-29T00:02:14.654Z",
"requestId": "abb6930d-2b57-4d44-9d63-19d5a9c8d077"
}
}
Common Error Codesβ
| Code | Status | Description |
|---|---|---|
unauthorized | 401 | Missing or invalid authentication |
forbidden | 403 | Insufficient permissions |
not_found | 404 | Resource not found |
validation_error | 400 | Request validation failed |
rate_limit_exceeded | 429 | Too many requests |
internal_error | 500 | Server error |
Request Trackingβ
Include X-Request-ID header for request tracking:
curl -H "X-Request-ID: debug-123" \
-H "soku-api-key: your_key" \
https://api.example.com/v1/posts
Error Loggingβ
Errors are logged to:
- Firestore:
errorLogscollection - Console: Immediate visibility during development
- Headers: Request ID for correlation
Development Modeβ
Set NODE_ENV=development for detailed error responses including stack traces.
Frontendβ
- Hooks and services under
apps/web/src/features/integrations: call these Functions endpoints with an ID token. startAuth(platform, idToken, returnTo, isLocal)creates a start-auth request and returns anauthUrlfor redirect.publish*services submit to/apiPublic API v1; orchestrator fans out topublish*provider functions.
Related backend: see Backend