Operate release marketing from GitHub to approved posts.
Ship 2 Post turns engineering release signals into branded, channel-ready content with approval control, API access, webhooks, billing gates, and auditability for production teams.
Source
GitHub
Generation
AI drafts
Delivery
Social + API
Quickstart
Connect a workspace, generate drafts, then use the API where automation needs to leave the browser.
Most teams begin in the webapp and add the API after the release workflow is stable.
- 1Create or select a workspace.
- 2Install the GitHub App from Repositories.
- 3Create a brand profile and channel templates.
- 4Create a trigger rule for release events.
- 5Review drafts, approve posts, and connect API consumers as needed.
Workspace API smoke test
# 1. Create an API key in S2P
# Settings -> API keys -> Create key
# 2. Read workspace state from the Convex HTTP API
curl https://<your-convex-site>/v1/workspace \
-H "Authorization: Bearer s2p_<token>"
# 3. List drafts ready for approval
curl 'https://<your-convex-site>/v1/drafts?status=ready' \
-H "Authorization: Bearer s2p_<token>"Core concepts
The domain model is intentionally small.
Everything belongs to a workspace. Repository signals become drafts through trigger rules, and only approved content becomes a post.
Workspace
The billing, membership, repository, API key, and publishing boundary.
Repository
A GitHub source watched for releases, tags, pull requests, and qualifying changes.
Brand profile
The company description, audience, voice, phrases, and compliance rules used by AI generation.
Channel template
A platform-specific content shape: length, structure, hashtags, links, and image behavior.
Trigger rule
Automation logic that decides when release signals should become draft posts.
Draft variant
One generated post candidate for one platform before approval or publishing.
How the webapp works
The webapp is the control plane for release automation.
Use it to connect sources, decide what should generate, edit output, approve publishing, and keep operational visibility in one place.
Connect GitHub
Install the S2P GitHub App, select repositories, and let release signals flow into the workspace.
Define brand and channels
Create brand profiles, voice rules, channel templates, and platform-specific constraints.
Create trigger rules
Choose which releases, tags, pull requests, or changelog updates should generate drafts.
Review generated drafts
S2P prepares channel-native variants, optional images, scores, and publishing metadata.
Approve and publish
Approve manually or use autonomous rules on eligible plans, then publish to connected destinations.
Measure and audit
Inspect posts, metrics, logs, and admin-only audit records for operational traceability.
Webapp pages
Every major page has one operational owner in the workflow.
This is the current implemented app surface: what each page is for, what it controls, and which pages are restricted by role, plan, or S2P-admin status.
Sources and automation
Repositories and trigger rules decide which GitHub events become release marketing work.
Content operations
Drafts, draft details, posts, and post details cover review, edit, approval, and publication state.
Reporting
Analytics and metrics endpoints expose performance where the plan includes analytics.
Workspace configuration
Settings covers identity, billing, team access, and AI model selection.
Billing gates
Plan and checkout surfaces control entitlements such as API access, image posts, and team members.
Admin observability
Logs and audit views are visible only to S2P admins with the backend boolean set to true.
| Page | Route | What it controls |
|---|---|---|
| Dashboard | /dashboard | Workspace overview, recent activity, setup progress, and operational shortcuts. |
| Repositories | /repos | GitHub App installation, repository inventory, ingestion health, repository removal, and repository plan limits. |
| Repository detail | /repos/:repoId | Repository-specific release signals, trigger context, connected state, and cleanup actions. |
| Brands | /brands | Brand profile creation, voice setup, positioning, do-use phrases, do-not-use phrases, and compliance rules. |
| Brand detail | /brands/:brandId | Brand profile editing and channel templates for platform-specific content structure. |
| Connections | /connections | Social OAuth starts, manual credentials, Bluesky app-password flow, refresh, disconnect, and custom webhook destinations. |
| Trigger rules | /triggers | Automation rules, active/inactive state, signal filters, brand selection, and channels. |
| New trigger rule | /triggers/new | Rule creation, platform selection, and required channel-template preparation. |
| Trigger rule detail | /triggers/:ruleId | Rule edits, activation toggles, approval-mode changes, channel changes, and rule deletion. |
| Drafts | /drafts | Generated draft queue, status filtering, approval, rejection, regeneration, archive, and bulk actions. |
| Draft detail | /drafts/:draftId | Variant review, body editing, approval decisions, image assets, citations, scores, and publish actions. |
| Posts | /posts | Published and scheduled post inventory, status filters, channels, and delivery state. |
| Post detail | /posts/:postId | Post payload, destination, external URL, delivery metadata, and performance context. |
| Analytics | /analytics | Workspace metrics, post analytics, channel performance, metric pulls, and export-gated reporting. |
| Archive | /archive | Archived drafts, posts, repositories, rules, and restore or hard-delete flows where supported. |
| API keys | /api-keys | Owner-only API key creation, scope selection, one-time plaintext display, revocation, and deletion of revoked keys. |
| Settings | /settings | Workspace identity, AI model selection, plan and billing, and team access control. |
| Logs | /logs | S2P-admin-only operational logs for backend review. |
| Audit | /audit | S2P-admin-only audit log review with resource, actor, action, and timestamp context. |
| Account | /account | User account preferences and account-level navigation. |
| Archived workspaces | /workspaces/archived | Workspace restore and permanent deletion flows for archived workspaces. |
Workspace bootstrap
On first authenticated use, S2P provisions a personal workspace when the user has no active membership.
Workspace selection
The selected workspace is stored locally and reconciled against the live membership list.
Billing gates
Locked features show upgrade dialogs in the UI and are also enforced in Convex mutations/actions.
GitHub ingestion
GitHub App webhooks create normalized release signals that trigger active matching rules.
AI pipeline
Draft generation gathers repository, signal, brand, voice, channel, recent draft, and billing context before calling OpenRouter.
Approval
Free workspaces require review before publishing. Eligible paid workspaces can use autonomous publishing.
Publishing
Approved variants publish to connected social destinations or custom webhooks when platform and plan rules allow it.
Auditability
Mutations and publishing operations write audit rows; visibility is restricted to S2P admins for logs and audit pages.
Archive and restore
Archive screens preserve recoverability before permanent deletion flows are allowed.
Membership and access
Member actions are role-gated and team-member features require the matching plan entitlement.
AI generation
S2P generates structured drafts, not one-off chat output.
The pipeline gathers release context, builds a release brief, creates channel variants, rewrites for brand voice, scores quality, and optionally generates image assets for eligible workspaces.
Release brief
The pipeline normalizes repository context into a concise angle, audience hook, customer value, and key points.
Channel variants
Templates control platform, length, structure, link behavior, hashtag ranges, and image requirements.
Model selection
Starter workspaces can choose premium text models. Growth workspaces can also choose image models.
Publishing destinations
Publishing starts only after the workspace is allowed to use the requested channel.
The billing and entitlement guard runs before drafts are generated and again before publishing operations that need paid features.
Connected social platforms
OAuth and credential-based destinations are managed in Connections. S2P stores publishing tokens server-side.
Custom webhooks
Use custom webhook channels when approved posts should go to a CMS, community bridge, static site builder, or internal system.
API authentication
Every public API request uses a workspace API key.
Create API keys from the app. Plaintext keys are shown once, stored only as hashes, and must be sent as bearer tokens.
- Header format: Authorization: Bearer s2p_<token>.
- API access is a Growth entitlement.
- Owner-level workspace permission is required to create keys.
- Keys are scoped to one workspace and can be revoked.
Authentication header
Authorization: Bearer s2p_<token>API reference
The v1 API exposes workspace operations for production integrations.
The v1 API is designed as the programmatic equivalent of the logged-in workspace UI. Use collection endpoints for lists and action endpoints for setup, settings, approval, publishing, archive, analytics, billing, and access-control operations.
Base URL
Use your deployed Convex HTTP Actions URL, then append /v1/...
Authentication
Send Authorization: Bearer s2p_<token> on every /v1 request.
JSON
Requests and responses are JSON unless a future endpoint states otherwise.
IDs
IDs are Convex document IDs. Invalid ids return validation_failed instead of leaking validator traces.
Pagination
List endpoints use limit and cursor where available, returning has_more and next_cursor.
Errors
Errors use { error, code, details? }. Common codes include validation_failed, forbidden, plan_required, not_found, and method_not_allowed.
Permissions
API scope, creator role, workspace membership, S2P admin status, and plan entitlement can all be checked.
| Resource | Methods | Primary path |
|---|---|---|
| Account | GET, PATCH | /v1/account |
| Workspace | GET, PATCH | /v1/workspace |
| Workspace settings | GET, PATCH actions | /v1/workspace/settings |
| Workspaces | GET, POST actions | /v1/workspaces |
| Billing | GET, POST actions | /v1/billing |
| API keys | GET, POST | /v1/api-keys |
| Repositories | GET, POST actions | /v1/repositories |
| Release signals | GET | /v1/release-signals |
| Trigger rules | GET, POST, PATCH, DELETE | /v1/trigger-rules |
| Brand profiles | GET, POST, PATCH, DELETE | /v1/brand-profiles |
| Channel templates | GET, POST, PATCH, DELETE | /v1/channel-templates |
| Social connections | GET, POST actions | /v1/social-connections |
| Drafts | GET, POST actions | /v1/drafts |
| Posts | GET | /v1/posts |
| Members | GET, POST, PATCH | /v1/members |
| Metrics | GET | /v1/metrics |
| Analytics | GET | /v1/analytics |
| Archive | GET, POST actions | /v1/archive |
| Onboarding | GET | /v1/onboarding/progress |
| Admin logs | GET | /v1/logs |
Response contract
{ "data": { "items": [] }, "meta": { "has_more": false, "next_cursor": null } }
{ "error": "Human readable message.", "code": "machine_readable_code" }API workflows
These workflows mirror what operators can do in the webapp.
Use this section when you need to automate the same actions that are available through the logged-in product surface.
First workspace setup
Create/list workspaces, read onboarding progress, start GitHub install, connect social destination, then edit the seeded brand profile and trigger rule.
/v1/workspaces, /v1/onboarding/progress, /v1/github/install/begin, /v1/social-connections/*, /v1/brand-profiles, /v1/trigger-rules
Workspace settings
Read resolved settings, update text/image models, and configure draft aggregation cadence with plan gates enforced. S2P branding lives in the in-app settings tab.
/v1/workspace/settings, /v1/workspace/settings/ai-models, /v1/workspace/settings/draft-aggregation
Draft review and aggregation
List ready drafts, aggregate multiple drafts into one, edit variants, approve or reject, then publish approved variants.
/v1/drafts, /v1/drafts/aggregate, /v1/draft-variants, /v1/drafts/approve, /v1/drafts/reject, /v1/drafts/publish
Analytics and operations
Read metrics, dashboard KPIs, analytics breakdowns, archive items, restore or hard-delete archived items, and inspect S2P-admin audit/log data.
/v1/metrics, /v1/analytics/*, /v1/archive, /v1/archive/restore, /v1/archive/delete, /v1/audit-logs, /v1/logs
Billing and access control
Read plan state, create checkout or billing portal sessions, invite members, update roles, revoke access, and manage API keys.
/v1/billing, /v1/billing/checkout, /v1/billing/portal, /v1/members, /v1/members/update-role, /v1/api-keys
Settings and model selection
# Read resolved settings and available model options
curl https://<your-convex-site>/v1/workspace/settings \
-H "Authorization: Bearer s2p_<token>"
# Update text and image model settings
curl -X PATCH https://<your-convex-site>/v1/workspace/settings/ai-models \
-H "Authorization: Bearer s2p_<token>" \
-H "Content-Type: application/json" \
-d '{"text_model":"~openai/gpt-mini-latest","image_model":"google/gemini-3-pro-image-preview"}'
# Configure aggregation cadence
curl -X PATCH https://<your-convex-site>/v1/workspace/settings/draft-aggregation \
-H "Authorization: Bearer s2p_<token>" \
-H "Content-Type: application/json" \
-d '{"enabled":true,"max_posts_per_window":1,"window_days":1,"auto_archive_source_drafts":true}'Draft aggregation and publishing
# Aggregate multiple ready drafts into one post-ready draft
curl -X POST https://<your-convex-site>/v1/drafts/aggregate \
-H "Authorization: Bearer s2p_<token>" \
-H "Content-Type: application/json" \
-d '{"draft_ids":["draftId1","draftId2"],"archive_source_drafts":true}'
# Approve the aggregate draft
curl -X POST 'https://<your-convex-site>/v1/drafts/approve?id=<draftId>' \
-H "Authorization: Bearer s2p_<token>"
# Publish approved variants
curl -X POST 'https://<your-convex-site>/v1/drafts/publish?id=<draftId>' \
-H "Authorization: Bearer s2p_<token>"Analytics and archive operations
# Read UI-equivalent analytics panels
curl https://<your-convex-site>/v1/analytics/dashboard?period=day \
-H "Authorization: Bearer s2p_<token>"
# Archive selected items
curl -X POST https://<your-convex-site>/v1/archive \
-H "Authorization: Bearer s2p_<token>" \
-H "Content-Type: application/json" \
-d '{"items":[{"kind":"draft","id":"<draftId>"}]}'
# Restore selected archived items
curl -X POST https://<your-convex-site>/v1/archive/restore \
-H "Authorization: Bearer s2p_<token>" \
-H "Content-Type: application/json" \
-d '{"items":[{"kind":"draft","id":"<draftId>"}]}'| Operation | Path | Request body | Notes |
|---|---|---|---|
| Update account | PATCH /v1/account | { email?, name?, avatar_url? } | Updates the API-key creator profile. |
| Create workspace | POST /v1/workspaces | { "name": "Workspace name" } | Seeds starter brand, channel template, and trigger rule. |
| Update AI models | PATCH /v1/workspace/settings/ai-models | { text_model?, image_model? } | Text model selection requires premium AI. Image model selection requires image posts. |
| Update draft aggregation settings | PATCH /v1/workspace/settings/draft-aggregation | { enabled, max_posts_per_window, window_days, auto_archive_source_drafts } | Requires draft aggregation entitlement. |
| Create checkout session | POST /v1/billing/checkout | { plan_slug, billing_cycle, return_path? } | Owner only. plan_slug is starter, growth, scale, or business. |
| Begin OAuth connection | POST /v1/social-connections/oauth/begin | { platform, redirect_after? } | Returns an auth_url for browser completion. |
| Connect Bluesky | POST /v1/social-connections/bluesky | { handle, app_password } | Credential-based connection without OAuth redirect. |
| Connect Mastodon | POST /v1/social-connections/mastodon | { instance_url, access_token } | Verifies credentials against the Mastodon instance. |
| Connect webhook destination | POST /v1/social-connections/webhook | { platform, webhook_url, label?, signing_secret? } | Supports discord, slack, hacker_news, substack, and custom_webhook. |
| Bulk draft action | POST /v1/drafts/bulk | { action, ids | draft_ids } | action is approve or reject. Archive drafts through /v1/archive. |
| Aggregate drafts | POST /v1/drafts/aggregate | { draft_ids, archive_source_drafts? } | Requires at least two ready drafts and draft aggregation entitlement. |
| Publish draft | POST /v1/drafts/publish?id= | { channelId? } | Schedules publish jobs for variants with active matching connections. |
| Archive, restore, or hard-delete items | POST /v1/archive, POST /v1/archive/restore, POST /v1/archive/delete | { "items": [{ "kind": "draft", "id": "..." }] } | Kinds include brand_profile, repository, trigger_rule, post, draft, job_run, and audit_log. job_run and audit_log require S2P admin access. |
| Invite member | POST /v1/members | { email, role } | Requires team member entitlement and member invite permission. |
| Update member role | PATCH /v1/members/update-role?id= | { role } | Uses membership id in the query string. |
| Create API key | POST /v1/api-keys | { name, scopes } | Plaintext key is returned once. |
Endpoint catalog
Every implemented public v1 HTTP route is listed here.
Paths are relative to your deployed Convex HTTP Actions URL. Query parameters shown with ?id= or ?postId= are required unless noted otherwise.
| Method | Path | Scope | Purpose and gates |
|---|---|---|---|
| GET | /v1/workspace | workspace:read | Read current API-key workspace metadata, plan, and status. |
| PATCH, POST | /v1/workspace | workspace:write | Update workspace name or slug. Structured settings use /v1/workspace/settings/*. |
| GET, PATCH, POST | /v1/account | account:read/write | Read or update the API-key creator account profile. |
| GET | /v1/workspace/settings | settings:read | Read resolved AI model, draft aggregation, branding, plan access, options, and presets. |
| PATCH, POST | /v1/workspace/settings/ai-models | settings:write | Update text and image AI models with the same tier checks as the UI. |
| PATCH, POST | /v1/workspace/settings/draft-aggregation | settings:write | Update draft aggregation cadence and source-draft archive behavior. |
| GET, POST | /v1/workspaces | workspaces:read/write | List account workspaces or create a new workspace with starter brand and trigger templates. |
| GET | /v1/workspaces/get?id= | workspaces:read | Get an account workspace by id. |
| POST | /v1/workspaces/archive?id= | workspaces:write | Archive a workspace. Owner only. |
| POST | /v1/workspaces/restore?id= | workspaces:write | Restore an archived workspace. Owner only. |
| DELETE, POST | /v1/workspaces/delete?id= | workspaces:write | Permanently delete an archived workspace and scoped data. Owner only. |
| GET | /v1/billing | billing:read | Read billing catalog, current plan, subscription, and workspace billing state. |
| POST | /v1/billing/checkout | billing:write | Create Stripe checkout or subscription update portal session. Owner only. |
| POST | /v1/billing/portal | billing:write | Create a Stripe billing portal session. Owner only. |
| GET | /v1/api-keys | api_keys:read | List API keys. Requires API key read permission. |
| POST | /v1/api-keys | api_keys:write | Create API key. Requires Growth API access and api_key create permission. |
| POST | /v1/api-keys/revoke?id= | api_keys:write | Revoke an API key by id. |
| DELETE, POST | /v1/api-keys/delete?id= | api_keys:write | Delete a revoked API key by id. |
| GET | /v1/repositories | repositories:read | List repositories. Supports status, limit, and cursor. |
| GET | /v1/repositories/get?id= | repositories:read | Get one repository by id. |
| GET | /v1/repositories/stats | repositories:read | Read per-repository trigger counts and recent signal counts. |
| GET | /v1/release-signals | repositories:read | List release signals by kind, repo_id, and limit. |
| GET | /v1/release-signals/get?id= | repositories:read | Get one release signal by id. |
| POST | /v1/github/install/begin | repositories:write | Start GitHub App installation for the workspace. |
| DELETE, POST | /v1/repositories/remove?id= | repositories:write | Remove a connected repository by id. |
| GET | /v1/brand-profiles | brand_profiles:read | List brand profiles with pagination. |
| POST | /v1/brand-profiles | brand_profiles:write | Create a brand profile and required voice context. |
| PATCH, POST | /v1/brand-profiles?id= | brand_profiles:write | Update a brand profile by id. |
| DELETE, POST | /v1/brand-profiles/delete?id= | brand_profiles:write | Delete a brand profile by id. |
| GET | /v1/brand-profiles/get?id= | brand_profiles:read | Get one brand profile by id. |
| GET | /v1/channel-templates?brandProfileId= | brand_profiles:read | List channel templates for a brand profile. |
| POST | /v1/channel-templates | brand_profiles:write | Add a channel template to a brand profile. |
| PATCH, POST | /v1/channel-templates?id= | brand_profiles:write | Update a channel template by id. |
| DELETE, POST | /v1/channel-templates/delete?id= | brand_profiles:write | Delete a channel template by id. |
| GET | /v1/channel-templates/get?id= | brand_profiles:read | Get one channel template by id. |
| GET | /v1/social-connections | social_connections:read | List connected publishing destinations. |
| POST | /v1/social-connections/oauth/begin | social_connections:write | Begin OAuth for supported social platforms. |
| POST | /v1/social-connections/bluesky | social_connections:write | Connect Bluesky with app-password credentials. |
| POST | /v1/social-connections/mastodon | social_connections:write | Connect Mastodon with instance URL and access token. |
| POST | /v1/social-connections/webhook | social_connections:write | Connect Discord, Slack, Hacker News, Substack, or a custom webhook destination. |
| POST | /v1/social-connections/test?id= | social_connections:write | Publish a test post through one active social connection. |
| POST | /v1/social-connections/refresh?id= | social_connections:write | Refresh one social connection by id. |
| POST | /v1/social-connections/disconnect?id= | social_connections:write | Disconnect one social connection by id. |
| GET | /v1/trigger-rules | trigger_rules:read | List trigger rules with pagination. |
| POST | /v1/trigger-rules | trigger_rules:write | Create a trigger rule with brand and channel template references. |
| GET | /v1/trigger-rules/get?id= | trigger_rules:read | Get one trigger rule by id. |
| PATCH, POST | /v1/trigger-rules?id= | trigger_rules:write | Update one trigger rule by id. |
| POST | /v1/trigger-rules/toggle?id= | trigger_rules:write | Toggle active state for a trigger rule. |
| DELETE, POST | /v1/trigger-rules/delete?id= | trigger_rules:write | Delete one trigger rule by id. |
| GET | /v1/drafts | drafts:read | List drafts. Supports status, signalId, limit, and cursor. |
| GET | /v1/drafts/get?id= | drafts:read | Get one draft and its variants by id. |
| POST | /v1/drafts/approve?id= | drafts:write | Approve a draft and queue publishing when applicable. |
| POST | /v1/drafts/reject?id= | drafts:write | Reject a draft by id. |
| POST | /v1/drafts/regenerate?id= | drafts:write | Request draft regeneration by id. |
| POST | /v1/drafts/bulk | drafts:write | Bulk approve, reject, or archive draft ids. |
| POST | /v1/drafts/aggregate | drafts:write | Aggregate multiple ready drafts into one ready draft. Requires draft aggregation entitlement. |
| POST | /v1/drafts/publish?id= | drafts:write + posts:write | Publish an approved draft to selected channel templates. |
| PATCH, POST | /v1/draft-variants?id= | drafts:write | Update one draft variant body or metadata by id. |
| POST | /v1/draft-variants/update?id= | drafts:write | Compatibility route for variant updates. |
| GET | /v1/posts | posts:read | List posts. Supports status, channel, limit, and cursor. |
| GET | /v1/posts/get?id= | posts:read | Get one post by id. |
| GET | /v1/members | members:read | List workspace members with pagination. |
| POST | /v1/members | members:write | Invite a member. Requires team_members plan entitlement. |
| PATCH, POST | /v1/members/update-role?id= | members:write | Update member role by membership id. |
| POST | /v1/members/revoke?id= | members:write | Revoke a membership by id. |
| GET | /v1/audit-logs | audit_logs:read | S2P admin only. Supports limit, cursor, since, until, actor_user_id, action, and resource_kind. |
| GET | /v1/audit-logs/get?id= | audit_logs:read | S2P admin only. Get one visible audit log by id. |
| GET | /v1/metrics | metrics:read | Read workspace analytics. Requires post_analytics. |
| GET | /v1/metrics/post?postId= | metrics:read | Read metrics for one post. Requires post_analytics. |
| GET | /v1/metrics/export | metrics:export | Export analytics. Requires analytics export plus analytics entitlement. |
| GET | /v1/analytics/dashboard | analytics:read | Read dashboard KPI rollup and sparkline data. |
| GET | /v1/analytics/top-posts | analytics:read | Read top posts by engagement for the analytics page. |
| GET | /v1/analytics/platform-breakdown | analytics:read | Read published post and metric totals grouped by platform. |
| GET | /v1/analytics/draft-funnel | analytics:read | Read generated, ready, approved, and published draft funnel counts. |
| GET, POST | /v1/archive | archive:read/write | List archived items or archive selected items. |
| POST | /v1/archive/restore | archive:write | Restore selected archived items. |
| DELETE, POST | /v1/archive/delete | archive:write | Permanently delete selected archived items. |
| GET | /v1/onboarding/progress | onboarding:read | Read first-steps progress for repo, social, brand, and trigger setup. |
| GET | /v1/logs | logs:read | S2P admin only. Read job run logs for the logs page. |
| POST | /v1/test/simulate-release | test:write | Development smoke-test endpoint. Do not enable in production deployments. |
| POST | /v1/test/cleanup | test:write | Development cleanup endpoint. Do not enable in production deployments. |
Scopes and permissions
A request must pass scope, role, membership, S2P-admin, and plan checks where applicable.
The token alone is not the whole authorization model. API handlers combine API key scopes with the key creator's current workspace membership and billing entitlement.
Authorization order
- 1Validate Authorization: Bearer s2p_<token>.
- 2Find API key by prefix and compare the stored hash.
- 3Reject revoked keys.
- 4Check the required API scope.
- 5Check the key creator still has an active workspace role with the required RBAC permission.
- 6Check S2P-admin status for audit-log endpoints.
- 7Check plan entitlement for gated operations such as API access, team members, analytics, and exports.
| Scope | Access |
|---|---|
| * | Full API access for the workspace. |
| account:read/write | Read or update the API-key creator profile. |
| workspace:read/write | Read or update current workspace metadata. |
| workspaces:read/write | List, create, archive, restore, and permanently delete account workspaces. |
| settings:read/write | Read or update AI models, draft aggregation, and S2P branding settings. |
| billing:read/write | Read billing state and create checkout or billing portal sessions. |
| repositories:read/write | List repositories, inspect release signals, begin GitHub installs, and remove repositories. |
| brand_profiles:read/write | Manage brand profiles and channel templates. |
| social_connections:read/write | List, connect, refresh, and disconnect publishing destinations. |
| trigger_rules:read/write | List, create, update, toggle, and delete automation rules. |
| drafts:read/write | List drafts, get variants, approve, reject, regenerate, bulk action, and edit variants. |
| posts:read/write | Read posts and publish approved drafts where the endpoint requires post write access. |
| members:read/write | List members, invite teammates, update roles, and revoke access. |
| audit_logs:read | Read audit logs. Also requires the API key creator to be an S2P admin. |
| metrics:read/export | Read analytics or export metrics when the plan includes those entitlements. |
| analytics:read/export | Read UI analytics models and analytics exports when plan entitlements allow them. |
| archive:read/write | List archive, archive items, restore items, and hard-delete items. |
| onboarding:read | Read first-steps onboarding completion state. |
| logs:read | Read job run logs. Also requires the API key creator to be an S2P admin. |
| api_keys:read/write | Manage API keys through the API. Requires API key RBAC permissions. |
| test:write | Development-only smoke-test and cleanup endpoints. |
Outbound webhooks
Webhook receivers should be fast, idempotent, and tolerant of retries.
Return any 2xx status for success. Use the idempotency key to avoid duplicate downstream publishing.
Example delivery headers
Content-Type: application/json
User-Agent: Ship2Post/1.0
X-Ship2Post-Platform: custom_webhook
X-Ship2Post-Idempotency-Key: post:123:custom_webhook
Authorization: Bearer <optional secret>Receiver checklist
- Validate the optional bearer secret when configured.
- Persist the idempotency key before publishing externally.
- Queue slow work and answer quickly.
- Return a public URL when your destination creates one.
Security model
Workspace boundaries, roles, and server-side secrets are the security baseline.
The browser never receives provider secrets. API keys, social tokens, GitHub secrets, and AI provider keys stay server-side.
RBAC
Owners, admins, editors, and viewers have different access to workspace, billing, member, API key, and publishing operations.
Key storage
API keys are generated once, hashed, prefixed for lookup, and never stored as plaintext.
Auditability
Workspace mutations, publishing actions, and admin-only logs keep operational review possible.
Billing and limits
Plan entitlements are enforced in the UI and backend.
The API and webapp share the same entitlement model, so locked features cannot be bypassed by calling Convex mutations directly.
Starter
Premium Text AI starts on Starter. Free workspaces use the fixed free text model.
Growth
API access, team members, release links, AI image posts, and image model selection begin on Growth.
Troubleshooting
Most setup issues resolve by checking source, entitlement, and credential state.
Use this sequence before debugging generated content quality or publishing delivery.
Confirm the selected workspace is active and on the expected plan.
Confirm the GitHub App is installed on the target repository.
Confirm the trigger rule is active and points at a brand profile plus channel templates.
Confirm each channel is available on the workspace plan.
Confirm connected social accounts have valid credentials.
Check logs and S2P admin audit views for backend failures.