Docs · page 01 of 09
Getting started with DraftADay Studio
DraftADay Studio lives at studio.draftaday.com. It is a LinkedIn writing desk that runs one loop: harvest posts from your own logged-in LinkedIn session with the Chrome extension, compose in your measured voice, schedule onto a calendar, publish through LinkedIn's official API (or by hand where no API exists), measure what the post actually did, and pollinate a winner into a new draft for another brand.
Everything you generate starts as a draft. A draft reaches LinkedIn only when you press 🔗 Publish now or put it on the calendar yourself. (The one exception is Overnight Autopilot, a flag-gated feature that is off by default — see What Studio never does for you.) The Chrome extension is read-only on LinkedIn, and its publish path always stops short of posting — you paste, review, and click Post.
The three ways in
1. The Caddy gate (still in front of the whole app)
Studio sits behind an HTTP basic-auth gate. Your browser shows its own username/password box before any of the app loads — that credential comes from your invite, not from Studio.
Some paths are deliberately open in front of the gate:
/health, and/version;/signin.htmland the OAuth round-trip (/api/auth/providers,/api/auth/start,/api/auth/callback,/api/auth/logout, the Facebook login start/callback, and the Facebook Pages callback);- the public front door —
/grade,/welcome,/public/*, the hosted newsletter pages/n/*, plus/card,/sampleand/r/*; - the Chrome extension's ingest endpoints (
/api/bridge/*,/api/feed/ingest,/api/feed/self-ingest,/api/feed/capture,/api/feed/writer-ingest,/api/library/ingest, the/api/network/*lookups,/api/onboarding/ingest,/api/posts/metrics-by-permalink,/api/outcomes,/api/settings,/api/media/upload-binary). A cross-origin fetch from an extension cannot do basic-auth, so these are guarded by thex-studio-tokenheader at the app instead.
Everything else, including / and the rest of /api, returns 401 without the basic-auth credential.
Good to know
The gate is independent of sign-in. You can complete a Google/Facebook sign-in successfully and still get the browser password box when you land on
/, because the app itself stays behindbasic_authuntil self-serve signup opens. If that happens you have not done anything wrong — you need the basic-auth credential too.
2. Social sign-in at /signin.html
The sign-in page asks the server which buttons it can actually complete (GET /api/auth/providers) and renders only those as live links. On this server today:
| Button | State |
|---|---|
| Continue with Facebook | live, works end to end |
| Continue with Google | not set up |
| Continue with Microsoft | not set up |
| Continue with email | not set up |
The three WorkOS-backed buttons stay disabled (dashed border, a not set up badge, hover text This server has no credentials for google yet.) until all three of WORKOS_API_KEY, WORKOS_CLIENT_ID and WORKOS_REDIRECT_URI are filled in on the server. A missing key never becomes a button that 500s.
A successful sign-in sets an httpOnly studio_session cookie for 30 days, and every /api request is authorised by that cookie. A brand-new user also gets a workspace created on the spot, named after their email address, with them as its owner.
Good to know
The connection pill in the top-right only ever reports the legacy token. If you signed in socially and have no token saved in this browser, the pill reads No token even though you are signed in and the app works. It is a stale label, not a failure.
Failures land you back on the sign-in page with the reason in the red box, for example:
That sign-in link expired. Please try again.
Facebook sign-in is not configured on this server.
3. The legacy Studio access token
Open Settings → Studio connection, paste the token your administrator issued, and press Save & test connection. The token lives only in that browser and is sent as the x-studio-token header. Forget token clears it; Show and Copy are there for checking it. The same card carries a Sign in with Google, Microsoft or Facebook link if you would rather use a session.
There is no self-serve reset for this token, by design. The card's Where do I find this? note says the same: it is not a LinkedIn or account password.
With a token saved, the pill reads Connected and the banner beneath it explains the state in full. The six banner texts, verbatim:
Enter your Studio token below to connect.
Not signed in. Sign in with Google, Microsoft or Facebook — or paste your Studio token below and Save & test connection.
Testing connection…
Connected. Your token is valid and the Studio is reachable.
The server rejected this browser. Sign in again, or paste the correct Studio token and Save & test.
Studio is offline or unreachable. Confirm it is running, then retry.
How a second login finds your existing account
The login key is the pair (provider, subject) in auth_identities — workos covers Google, Microsoft and email; facebook is its own provider. Resolution runs in a fixed order, and the order is the security model:
- A matching
(provider, subject)row → that user, always. - Otherwise, a user with the same email → link a new identity to them, only if the provider asserts the email is verified. This is how "I signed up with Google, now I press Facebook" lands on the same account.
- Otherwise, create the user and the identity.
An unverified email never links and never creates one:
the sign-in provider did not verify this email address, so it cannot be used to sign in
A provider that shares no email at all can never create an account, because a user row requires one:
Facebook did not share an email address for this account. Sign in with Google or Microsoft, or allow the email permission on Facebook.
Vocabulary, before anything else
- Workspace — your tenant. Every post, contact, brand and setting belongs to exactly one, and row-level security keeps them apart.
- Post — the source document: body text, hashtags, media, schedule. One post, many destinations.
- Brand — who a post goes out as. Either
personalor apage. Every connected account belongs to exactly one brand. - Publication — one post × one brand × one platform × one account. It carries its own optional body/hashtag/media override, its own outcome and its own permalink.
- Status, on the post:
draft→scheduled→publishing→published,failed, ormanual.manualis a terminal outcome meaning the composer-reminder path ran and you finish the share by hand; it never re-fires on its own.
First-run checklist
- Open studio.draftaday.com, clear the browser's gate prompt, then sign in — or paste your token in Settings → Studio connection and press Save & test connection until the pill reads Connected.
- Settings → LinkedIn account → Connect LinkedIn. Approve on LinkedIn's own consent page; you return with a "LinkedIn connected" toast and the card shows Connected as your name.
- Settings → Voice. Check Name, Identity / headline, Audience, Content pillars (one per line), Employer and Sign-off (DMs), then Save voice. If the status line reads "Measured voice card active", Studio has already distilled your real tone from your own posts.
- Install the Chrome extension: unzip the folder we sent, open
chrome://extensions, turn on Developer mode, click Load unpacked and pick the folder. Then click the extension icon → Settings to open its Options and fill in Studio URL (Send to Studio) =https://studio.draftaday.com(it must start withhttps://), Studio token (x-studio-token), and My LinkedIn profile URL. Press Save. - Harvest a handful of your own posts: open your LinkedIn profile → Activity → Posts, then click the extension icon → Scan tab → Harvest my posts (this page). Wait for "Harvested N of your posts into Studio". These are stored apart from the Feed tab (which holds other people's harvested posts) and are what the voice fingerprint, the voice samples and the experience bank read. The fingerprint stays silent until it has at least five of your posts of roughly 300 characters or more.
Your first post, end to end
- Open Compose.
- Give it a seed: type a Theme, click a chip under 💡 Trending topics, paste something into Seed the Idea · or improve a post, or pick one under Seed from a harvested post. Generate package stays disabled until at least one seed exists.
- Press Generate package and watch the live steps run.
- Edit what comes back — post text, two alternate hooks, hashtags, a best time, a first comment.
- Check the Scroll-stop preview. It mirrors where LinkedIn folds a post behind "…see more": roughly the first 210 characters or the first 3 line breaks, whichever comes first.
- Under Media for this post, pick exactly one of Text only, Images, Carousel PDF or Video. Kinds with nothing attached are greyed out. As the tray says: "LinkedIn publishes ONE media type per post — this is what Publish / Schedule will send."
- Finish with Save draft, 📅 Schedule… then Confirm schedule, or 🔗 Publish now (it asks you to confirm, and saves first).
Good to know
One successful Generate package costs one beta generation. A failed run never counts — the counter is bumped only after the generation succeeds.
What Studio never does for you
- It never auto-publishes a draft. Drafts stay drafts until you schedule or publish them. The single exception is Overnight Autopilot: it ships disabled, and even when enabled it leaves the next day's posts as reviewable drafts on their slots unless the owner explicitly turns on its auto-publish setting, which files them as
scheduledinstead. - The extension never posts, comments, connects or sends messages on your behalf. It reads the page you are already looking at.
- The extension's 📤 Publish to LinkedIn button copies the finished post to your clipboard, downloads the media you ticked, and opens LinkedIn's composer. You paste with ⌘V / Ctrl+V, drag the media in, review, and click Post yourself — LinkedIn walls its composer off from auto-fill, so nothing is typed, attached or submitted for you.
- Newsletter generation is drafts-only behind a hard human approval gate: nothing distributes from an issue that is not
approved. Pollinate on a hit creates a new draft for another brand and publishes nothing.
The map
The top app bar carries six tabs: Calendar, Feed, Hits, Network, Compose, Newsletter. The avatar menu on the right holds Accounts, Settings, Help, and two entries that ship hidden:
- Profile Studio — appears only when the server reports
features.profileStudio(PROFILE_STUDIO_ENABLED). - Command Center — appears only when
features.commandCenter(COMMAND_CENTER_ENABLED) is on and your session passes an operator probe againstGET /api/command/overview. A non-operator session gets a 403 and the entry stays hidden.
Other flags gate cards rather than whole views: voiceCard, voiceReps, visionSeed, momentum, winLog, trackedLinks, agencySamples, captureGovernance, autopilot.
Beta reality today
- Access tokens are issued by hand by the administrator. No self-serve signup, no password reset.
- Non-owner workspaces have a lifetime cap of
BETA_GEN_LIMITpost generations, default 5. The owner workspace (workspace-0) is uncapped. When you hit the cap, generation returns HTTP 403 with:
beta limit reached — this beta account includes 5 post generations and you've used all of them. Message Mustafa to top up.
- Credits are granted by hand. There is no Stripe path yet; the owner grants them through an owner-only admin endpoint (
POST /api/admin/credits/grant, 403 for anyone butworkspace-0), and your balance and last 20 ledger lines are readable atGET /api/credits.
Where to go next
- Compose and voice — themes, seeds, the judge loop, the experience bank, and what actually moves output quality.
- Destinations and publishing — brands, publications, scheduling, hand-off targets, and reconnecting LinkedIn.
- The Chrome extension — install, harvest, capture, and the read-only guarantees.