Skip to content
On this page

Help center

Kairoset documentation

Everything you need to publish everywhere — whether you’re scheduling your first post or running Kairoset for fifty clients on your own domain.

Getting started

  1. Create your account. Sign up with your email. You get a workspace automatically — rename it and set its timezone in Settings → Workspace.
  2. Connect channels. Open Channels → Add channel, pick a network and approve access. Connect as many accounts as you need; group them by client with Customers.
  3. Compose. Press Create post, select channels, write once, then switch to a channel tab to customize its copy, media or network-specific settings. Problems are flagged before you can schedule.
  4. Schedule. Pick a time or a preferred slot. Drag posts on the calendar to reschedule. The publishing engine handles retries and token refresh.
  5. Bring your team. Invite people in Settings → Team as owner, admin, editor or viewer, and send clients a share link to approve posts without an account.

Connecting networks

On a hosted Kairoset plan, networks are pre-configured: just click Add channel. If you operate your own instance, each OAuth network needs a developer app owned by you. Register the callback URL shown for each network — it is always APP_URL/api/oauth/<provider>/callback, computed here for https://kairoset.com — then set the env vars and redeploy. Networks without keys are hidden from users as “not configured”.

Networks that need a developer app

LinkedIn

OAuth appLinkedIn Developers
  1. Create an app (it must be associated with a LinkedIn Page you administer).
  2. Request the “Share on LinkedIn” and “Sign In with LinkedIn using OpenID Connect” products.
  3. In the Auth tab add the callback URL below to Authorized redirect URLs.
  4. Copy the Client ID and Primary Client Secret.

Callback / redirect URL

https://kairoset.com/api/oauth/linkedin/callback

Environment variables

LINKEDIN_CLIENT_IDLINKEDIN_CLIENT_SECRET
  • Access tokens last about 60 days; refresh tokens are only issued to apps approved for programmatic refresh.

LinkedIn Page

OAuth appLinkedIn Developers
  1. Use the same LinkedIn app as for profiles.
  2. Request the “Community Management API” product (requires LinkedIn review).
  3. Add this provider’s callback URL below to the app’s redirect URLs as well.

Callback / redirect URL

https://kairoset.com/api/oauth/linkedin-page/callback

Environment variables

LINKEDIN_CLIENT_IDLINKEDIN_CLIENT_SECRET
  • Company page posting is unavailable until LinkedIn approves Community Management API access.

Facebook Page

OAuth appMeta for Developers
  1. Create a Business-type app and add the “Facebook Login for Business” product.
  2. Add the callback URL below to Valid OAuth Redirect URIs.
  3. Request pages_show_list, pages_manage_posts, pages_read_engagement and business_management.
  4. Copy the App ID and App Secret (Settings → Basic). Add your privacy policy URL (/privacy) and data deletion URL (/privacy#data-deletion).

Callback / redirect URL

https://kairoset.com/api/oauth/facebook/callback

Environment variables

FACEBOOK_APP_IDFACEBOOK_APP_SECRET
  • Advanced access for other people’s Pages requires Meta App Review and Business Verification.

Instagram

OAuth appMeta for Developers
  1. Use your Meta app and add the Instagram Graph API.
  2. Request instagram_basic and instagram_content_publish in addition to the Pages permissions.
  3. Add the callback URL below. The Instagram account must be a Business/Creator account linked to a Facebook Page.

Callback / redirect URL

https://kairoset.com/api/oauth/instagram/callback

Environment variables

FACEBOOK_APP_IDFACEBOOK_APP_SECRET
  • Media must be reachable at a public URL (use Vercel Blob in production).

Instagram (direct login)

OAuth appMeta for Developers
  1. In your Meta app add “Instagram API with Instagram Login”.
  2. Add the callback URL below under Business login settings → OAuth redirect URIs.
  3. Copy the Instagram App ID and App Secret (they differ from the Facebook app credentials).

Callback / redirect URL

https://kairoset.com/api/oauth/instagram-standalone/callback

Requires an https URL — use your production domain or a tunnel for local testing.

Environment variables

INSTAGRAM_APP_IDINSTAGRAM_APP_SECRET

YouTube

OAuth appGoogle Cloud Console
  1. Create a Google Cloud project (or reuse the one for Google sign-in) and enable the YouTube Data API v3.
  2. Configure the OAuth consent screen (External) with your home page, privacy policy and terms URLs, and add the youtube.upload, youtube.readonly and youtube.force-ssl scopes.
  3. Publish the consent screen to “In production”. In Testing, Google expires every login after 7 days and channels disconnect weekly.
  4. Create an OAuth client ID of type “Web application” (or reuse your sign-in client) and add the callback URL below.
  5. Copy the Client ID and Client Secret, then submit the app for verification in the Google Auth Platform.

Callback / redirect URL

https://kairoset.com/api/oauth/youtube/callback

Environment variables

YOUTUBE_CLIENT_IDYOUTUBE_CLIENT_SECRET
  • Until Google verifies the app (sensitive scopes, usually a few weeks), people see an “unverified app” warning and at most 100 users can connect.
  • Uploads have their own quota: 100 videos per day per Google Cloud project, shared by every workspace on your instance. Request an extension through the YouTube API Services audit early.

TikTok

OAuth appTikTok for Developers
  1. Create an app and add the Login Kit and Content Posting API products (enable Direct Post).
  2. Add the callback URL below as a redirect URI.
  3. Verify ownership of your media domain (URL prefix) so TikTok can pull uploaded videos.
  4. Copy the Client Key and Client Secret.

Callback / redirect URL

https://kairoset.com/api/oauth/tiktok/callback

Requires an https URL — use your production domain or a tunnel for local testing.

Environment variables

TIKTOK_CLIENT_KEYTIKTOK_CLIENT_SECRET
  • Until TikTok audits your app, posts can only be published privately (SELF_ONLY).

Deploying to Vercel

  1. Database. Create a Postgres database — Neon from the Vercel Marketplace is the quickest. Copy the pooled connection string into DATABASE_URL.
  2. Import the repository into Vercel (framework preset: Next.js). The vercel-build script applies database migrations before every build.
  3. Media storage. Create a Vercel Blob store and connect it to the project; this sets BLOB_READ_WRITE_TOKEN. Networks such as Instagram and TikTok fetch media from public URLs.
  4. Cron. vercel.json registers /api/cron/publish every minute and /api/cron/refresh-tokens hourly; Vercel sends Authorization: Bearer $CRON_SECRET automatically. On the Hobby plan crons run daily at most — point an external scheduler (cron-job.org, GitHub Actions, Upstash QStash) at https://kairoset.com/api/cron/publish with that header every minute instead.
  5. Environment. Set the variables below, deploy, and check /api/health returns {"ok":true}.
Vercel → Settings → Environment Variables
APP_URL=https://kairoset.com
DATABASE_URL=postgres://…pooler…/db?sslmode=require
DATABASE_URL_UNPOOLED=postgres://…direct…/db?sslmode=require  # direct URL for migrations (required for Supabase :6543)
AUTH_SECRET=$(openssl rand -base64 32)
ENCRYPTION_KEY=$(openssl rand -base64 32)
CRON_SECRET=$(openssl rand -hex 32)
BLOB_READ_WRITE_TOKEN=vercel_blob_rw_…
VariableDescription
APP_URLrequiredPublic base URL, no trailing slash. Used for OAuth callbacks, emails and canonical links.e.g. https://social.example.com
DATABASE_URLrequiredPooled Postgres connection string (Neon, Vercel Postgres, Supabase).e.g. postgres://user:pass@host/db?sslmode=require
AUTH_SECRETrequiredRandom secret for signed values.e.g. openssl rand -base64 32
ENCRYPTION_KEYrequiredBase64 of exactly 32 bytes; encrypts channel tokens at rest. Never rotate after channels are connected.e.g. openssl rand -base64 32
CRON_SECRETrequiredProtects /api/cron/*. Vercel Cron sends it as a Bearer token automatically.e.g. openssl rand -hex 32
BLOB_READ_WRITE_TOKENVercel Blob token for media storage (required in production for media posts).
RESEND_API_KEYTransactional email. Unset: emails are printed to the server log.
EMAIL_FROMSender for transactional email.e.g. Acme Social <noreply@acme.com>
STRIPE_SECRET_KEYEnables billing. Unset: every workspace is unlimited (self-host / white-label mode).
STRIPE_WEBHOOK_SECRETSigning secret for /api/stripe/webhook.
ANTHROPIC_API_KEYEnables the AI writing assistant.
ALLOW_SIGNUPS"false" makes the instance invite-only; marketing CTAs switch to “Request access”.e.g. true
REQUIRE_SIGNUP_APPROVALNew self-serve accounts wait for a super-admin to approve them (Admin → Users) before they can sign in. "false" turns the queue off.e.g. true
SUPER_ADMIN_EMAILSComma-separated emails that become instance operators.

White-labeling for agencies & resellers

Every customer-facing string, colour and legal detail comes from configuration, so a reseller instance is a deploy — not a fork. Create a separate Vercel project from the same repository for each client brand (or run one instance with a workspace per client), attach the client’s domain, and set:

VariableDescription
NEXT_PUBLIC_BRAND_NAMEProduct name everywhere: header, emails, legal pages, OG images.e.g. Acme Social
NEXT_PUBLIC_BRAND_TAGLINEShort tagline used in titles and the footer.
NEXT_PUBLIC_BRAND_LOGO_URLSquare logo URL. Unset: the built-in mark in your brand colours.
NEXT_PUBLIC_BRAND_PRIMARYPrimary accent colour (hex).e.g. #f97316
NEXT_PUBLIC_BRAND_SECONDARYSecondary gradient colour (hex).e.g. #facc15
NEXT_PUBLIC_SUPPORT_EMAILSupport/contact address shown on the site and legal pages.
NEXT_PUBLIC_BRAND_DOMAINYour public domain, shown in legal pages.e.g. social.acme.com
NEXT_PUBLIC_BRAND_POWERED_BY"false" hides the “Powered by Kairoset” footer credit.

Privacy and Terms are templates driven by these variables. Until they’re set, pages show highlighted placeholders and a notice. Have counsel review the final text.

VariableDescription
NEXT_PUBLIC_LEGAL_ENTITYLegal name of the operator (data controller / contracting party).e.g. Acme Media Ltd
NEXT_PUBLIC_LEGAL_ADDRESSRegistered postal address.e.g. 1 Example Street, London, UK
NEXT_PUBLIC_LEGAL_JURISDICTIONGoverning law and courts for the Terms.e.g. England and Wales
NEXT_PUBLIC_LEGAL_EFFECTIVE_DATEEffective date shown on Privacy and Terms.e.g. 2026-11-01
NEXT_PUBLIC_PRIVACY_EMAILAddress for privacy / data requests (defaults to the support email).

Reseller checklist

  • Register each network’s developer app under the reseller’s business, using callback URLs on the reseller’s domain.
  • Leave STRIPE_SECRET_KEY unset for an unlimited, billing-free instance — or set it to bill clients directly.
  • Set ALLOW_SIGNUPS=false for invite-only instances; the site’s calls-to-action switch to “Request access”.
  • NEXT_PUBLIC_* values are inlined at build time — redeploy after changing them.

API & MCP

Everything you can do in the calendar you can automate. Create an API key in Settings → API (shown once, stored hashed) and call the REST API at https://kairoset.com/api/v1 with Authorization: Bearer orb_…. Subscribe to signed webhooks for post.published and post.failed.

The MCP server lets Claude and other agents list channels, draft and schedule posts in plain language. Add it to an MCP client with your API key:

MCP client configuration
{
  "mcpServers": {
    "kairoset": {
      "url": "https://kairoset.com/api/mcp",
      "headers": { "Authorization": "Bearer orb_your_api_key" }
    }
  }
}

Full endpoint reference: API reference →