What we shipped.
A running record of the platform work that matters to agent builders and cohort users — newest first.
Each release block lists what changed and why. Releases that ship a new SDK version get their own permalink at /changelog/<slug> with version chips linking to the npm or PyPI page; in-page anchors stay reachable as #r-<date>. Every PR with user- or builder-visible impact lands a Fixed / Added / Changed / Security / Infrastructure entry here — enforced by CI.
Updated
A transitive advisory pinned out of the frontend build
- Security
Pinned
source-map-jsto 1.2.2 through an override. The advisory (GHSA-68fv-2mgg-jv7q, an indexed source-map can stall the event loop) landed against the version Vite pulls in transitively, which turned the CI dependency audit red on commits that were green when they were cut.
- Security
Page counts from our own CDN logs
- Changed
agentdraft.io's CDN request logs now feed a daily page count to VectraSEO, our SEO analytics service. Raw logs stay in a private bucket for 7 days; only aggregates leave it — path, referring site, browser or crawler name, status category and
utm_*tags, with any referrer, country, browser, campaign tag or non-existent page address seen fewer than 3 times a day grouped as "other". No IPs, cookies or other URL parameters are sent, and sign-in, onboarding and dashboard pages are never included. The privacy policy's "Cookies and analytics" and "Sharing" sections describe it.
- Changed
Opt-in visit analytics on the public site
- Added
The marketing site now asks before loading Google Analytics 4. Declining, or sending a Global Privacy Control signal, means the script is never fetched. If you accept, page views record only the path and
utm_*tags. GA4 is switched off at the router before any navigation into sign-in, onboarding, or the dashboard, so authenticated pages are never reported. Google signals and ad personalization are off, and "Cookie settings" in the footer changes your choice at any time.
- Added
The paragraphs were always there — now the markup says so
- Fixed
Nine posts shipped their body copy as bare text between headings. Browsers collapsed the whitespace into readable paragraphs, but anything reading
<p>elements — including VectraSEO's answer-structure check — saw only headings and stray citation notes, which is why those posts kept failing the check even after they had a real answer block. Both the API renderer and the static build now wrap top-level text in paragraphs, and the FAQ answers those posts already carried get their<p>too. - Fixed
Dead OWASP links across nine posts now point at the projects' current hosts —
top10.owasp.orgfor the Top 10 andgenai.owasp.orgfor the LLM Top 10 and the prompt-injection entry. The oldowasp.org/www-project-*URLs 404 for some crawlers mid-migration. Like the earlier OpenAI fix, the rewrite is applied when a body is rendered, so it also survives a republish from VectraSEO. - Fixed
/docsno longer nominates a.ledeelement in itsspeakableJSON-LD. The page has no such element, so the scope resolved to nothing; it now lists the selectors the docs page actually renders. - Fixed
Expired holds stopped blocking the calendar. A hold reserves a slot for 30 seconds, and the conflict engine already lets a new booking take the slot once that window passes — but availability, the A2A availability skill, the dashboard booking list, and the calendar audit kept treating the stale row as live until DynamoDB's lazy TTL cleanup ran, which can take hours. All four readers now check the hold's own TTL before counting it.
- Fixed
Every post now answers its own question
- Added
119 blog posts now open with a direct answer block — 40 to 85 words that answer the question the post is titled after, before the post starts explaining it. Eleven posts already had one; the rest opened straight into prose, so an answer engine asking "what is agentic calendar conflict resolution" had to infer an answer from the whole article. Every indexed post now carries one, which is 130 of them.
- Changed
The 16 posts held out of the search index deliberately did not get a block, and a test now keeps it that way. The block exists to be extracted — the page nominates
.answer-blockas its speakable passage — and anoindexpage is not going to be extracted, so an entry there is two maps to keep in sync forever in exchange for nothing. - Fixed
/emailnow redirects to the mailbox docs instead of returning a 404. Posts describing "AgentDraft's Email box for Agents" linked there, but only the/calendarside of that redirect family was ever filled in — so a page ranking in search sent readers to a dead end./email-boxand/email-for-agentsare covered too, and a test now fails the build if either family loses an alias or points at a route that no longer exists. - Added
New integration page at
/integrations/crewai, plus a workedexamples/crewai_quickstart.py— the ~20-linecrewai.tools.BaseToolsubclass that gives a Crew race-free availability and booking tools over theagentdraftSDK. Google has been probing a CrewAI scheduling slug under eight different URL prefixes for a page that didn't exist, and CrewAI was the one major agent framework without its own page. - Fixed
Corrected a compatibility claim we had been repeating everywhere: **CrewAI cannot consume the
agentdraft-langchaintools.** CrewAI validatesAgent(tools=…)against its owncrewai.tools.BaseTooland raises a PydanticValidationErroron alangchain_coretool, andTool.from_langchain()doesn't bridge it either — it requires a callable.functhat a hand-writtenBaseToolsubclass doesn't have. Verified againstcrewai1.15.20 andlangchain-core1.6.2; the AutoGen half of the same sentence does work and is unchanged. The claim is corrected on every page, in both PyPI READMEs, and in the module docstrings, and a test now fails the build if it comes back.
- Added
What the page says when you take the tags off
- Fixed
Three headlines were running their words together for anything that reads the page as text. The home page announced itself as "Turn meeting requestsinto bookings.Keep your agentsin sync.", the pilot page as "Move your scheduling agentfrom demo to production.", and pricing as "Pricing should beboring infrastructure." All three looked correct on screen: the line breaks were doing the spacing, and the template compiler had removed the whitespace around them. The site nominates its
h1as the passage answer engines should quote and voice assistants should read aloud, so that was the sentence being handed to them. - Changed
/docswas titled "The AgentDraft protocol specification" — which is/spec's subject, not its own. It is the API reference: quick start, endpoints, error codes, audit log. Two pages claiming the same identity left them competing for the same searches. - Changed
Four page titles said only what section of the site you had landed in. "Blog", "Docs", "Security", and "Pricing" now say what is on the page, which is the only thing a search result has to work with. Pricing's summary also stopped at the $25 plan and omitted Scale, implying $25 was the ceiling for self-serve.
- Fixed
The pages nobody could reach
- Fixed
The Enterprise button on
/pricingis now a real link. It always went to/pilot, but through a click handler rather than anhref— so it couldn't be opened in a new tab, and search engines never saw the edge at all./pricingis linked from every page on the site, which made this one of the few strong paths to the pilot page; without it,/pilothad two inbound links in total. The four paid plans are unchanged: those buttons start a checkout rather than navigating. - Added
Six pages that could only be reached from an index now have links from the pages that actually discuss them. The webhooks guide links to the payload-debugging and latency deep dives and to the Nightlamp writeup; email-flow monitoring links to that writeup too, having previously named Nightlamp while linking only off-site; the calendar API links to the Alaska Road Trip study; the coordination layer and negotiation pages link to their respective guides.
- Fixed
A blog post no longer links to a retired OpenAI documentation page. The URL redirected to a page that 404s, which is easy to miss because the first hop looks healthy. Post bodies are authored upstream and can't be edited through that API, so known-dead outbound links are now repointed as the post is ingested — which also means a republish can't bring the dead link back.
- Infrastructure
Deploys now verify that a nonexistent URL returns
404, that the app subdomain redirects the apex'ssitemap.xml,rss.xml,changelog.rss, andllms.txt, and that itsrobots.txtstill resolves. These behaviours live in the CDN configuration rather than the site bundle, so no test suite could see them and a regression would only have surfaced in Search Console weeks later.
- Fixed
Dead URLs stop pretending to be the home page
- Fixed
A URL that doesn't exist now answers
404. Every missing object used to return200with the home page's HTML — its title, itscanonical— so any invented path became a live page. Search Console had logged the result as soft 404s, with one slug that was never published crawled under seven different path prefixes (/blog/,/posts/,/articles/,/news/, …), and the apex was advertising an unbounded set of duplicates of itself. Real routes are unaffected: each one is pre-rendered to its own file, so a missing object was already proof the route wasn't real. - Fixed
Blog posts no longer print their own summary twice. The header rendered the lede, then rendered it again as the page's "direct answer" whenever the post had no hand-written one — which was 139 of 146 posts. Because the page's
speakablestructured data points at that element, every one of those posts was nominating a marketing teaser as the passage answer engines should read aloud. Seven posts covering CRM sync, email threading, calendar conflict resolution, draft management, error handling, and event metadata gained a real answer block instead. - Fixed
app.agentdraft.iostopped serving the apex'ssitemap.xml,rss.xml,changelog.rss, andllms.txt. They were byte-identical objects in the same bucket, so Google — whose property covers every subdomain — crawled the whole marketing site a second time under the app host and logged 28 blog URLs as "Page with redirect". They now redirect to the apex. - Added
/pilotcarries a visible "Updated" line and adateModifiedin its structured data. The highest-intent page on the site had no page-level entity at all, so answer engines had nothing to date it by. - Added
Internal links from
/auditto the audit-trail and human-approval deep dives, and from/vs/agentmailto the AgentMail alternatives page. Footer-linked pages carry a link from all 176 URLs; everything else had exactly one. The three pages that earn the site's highest-intent search impressions were all in the second group.
- Fixed
A plan between Team and a sales call
- Added
**Scale** — $99/month for 25 users, 25 mailboxes, unlimited agents, and 100,000 bookings a month. Team's five-mailbox ceiling was the first wall most workspaces hit, and the only thing above it was a $5k–$20k annual pilot. Scale is self-serve: upgrade from the billing page, no conversation required. Every metered limit moves with the mailbox count, so you don't clear one ceiling and meet another.
- Added
Plans granted outside Stripe can now be locked. A manually set tier used to survive only until the next subscription event carrying that workspace's id — a cancellation reset it to the free tier, a renewal repriced it back to whatever the old subscription was billing for, and both happened silently. A locked plan is refused by the billing webhook at the storage layer, and a failed charge on an unrelated invoice can no longer start a countdown against it.
- Fixed
The billing page told free workspaces they had a dedicated CSM and 7-year audit — the plan summary fell through to the Enterprise description for any tier without an explicit case. Each plan now carries its own.
- Fixed
The pricing page's structured data caught up with the page itself. Search engines were told the booking allowance stopped at Team's 10,000, and never saw the question explaining what to do after the fifth mailbox — the FAQ is authored once for readers and once for crawlers, and only the first copy had learned about Scale. The two are now checked against each other, and
/pricingand/changelogreport the date they were actually last edited.
- Added
A direct path to production pilots
- Added
Teams can request a scoped production pilot without an account, with a saved inquiry, team inbox notification, and clear commercial expectations.
- Changed
Homepage and pricing calls to action connect production buyers to pilot scoping and clarify separate booking and mailbox limits.
- Fixed
Pilot submissions preserve the submitted contact address, allow retries after stalled requests, and keep form details out of URLs before JavaScript loads.
- Fixed
The mobile navigation and booking-conflict walkthrough fit narrow phone screens.
- Added
Two priced limits start applying
- Added
calendars_per_seatis enforced. Developer and Individual connect 1 calendar, Team 3 per seat, Enterprise unlimited — the numbers that have been on the pricing page all along. Connecting past the cap returns402 quota_exceededfrom every path (Google OAuth, Folio, ICS), and the count is held in a conditional counter committed in the sameTransactWriteItemsas the connection row, so two concurrent connects can't both slip through. Reconnecting a calendar you already have refreshes its tokens without spending a slot, and disconnecting frees one immediately. - Added
audit_retention_daysis enforced.GET /v1/dashboard/auditno longer returns events older than your plan keeps — 7 days on Developer, 30 on Individual, 1 year on Team, 7 years on Enterprise — and reportsretention_daysso the dashboard can say so instead of looking empty. Audit rows now carry a DynamoDB TTL derived from the tier at write time; upgrading lengthens retention for events written after the upgrade, not before. - Changed
The audit page names your retention window in its header and, when a range filter reaches past it, says which days it is showing and why.
- Fixed
The ICS 5-feed limit and the calendar cap are now separate limits with separate messages. The feed limit bounds what one provider can cost us regardless of plan; the calendar cap is the entitlement, and on every plan below Enterprise it binds first.
- Added
The homepage stops contradicting the pricing page
- Fixed
The homepage said the free Developer tier gives 1 agent. It gives 3, and has since the tier was widened so a free workspace can actually watch two agents collide.
/pricingwas corrected at the time; the homepage card was missed, so the two pages disagreed about what signing up gets you. Both now read from the same tier table, checked on every build. - Fixed
Multi-agent priority resolutionis no longer sold as the Team unlock. It was never gated — every tier runs the same conflict engine, and the free tier's three agents exist specifically so priority resolution can be tried before paying. The claim was removed from/pricingonce already; it survived on the homepage and in the dashboard's billing panel, which reported aMulti-agent priority: yes/noline driven by a flag no code ever read. The flag is deleted. - Changed
Tier attributes now have to gate something to exist. A new check fails the build when an entitlement is declared and displayed but never consulted — the exact shape of the defect above — with the two remaining unbacked attributes listed explicitly rather than left to be rediscovered.
- Fixed
- Changed
The TypeScript SDK is now
npm install agentdraft, matchingpip install agentdraftexactly. It shipped as@agentdraftio/sdkbecause the@agentdraftscope is held by an inactive account — but the unscoped name was free the whole time, and guessing the install command is the first thing anyone tries. The old package stays on npm, deprecated with a pointer to the new one. - Fixed
agentdraft-mcpon PyPI advertised its source, issue tracker, and changelog undergithub.com/GipsyChef/agentdraft— an org that no longer exists, so all three links 404'd. PyPI release metadata cannot be edited after upload, so this is fixed by releasing0.1.1. The Python SDK's0.1.1shipped with no repository link at all;0.1.2adds one. - Fixed
The script that generates the published install commands had a hardcoded
@agentdraft/sdk— a package this project does not own — that would have overwritten the correct commands on the next site build. It now reads every package name from the manifest it releases from, so the docs cannot advertise a package that isn't ours. - Added
The MCP server carries a
server.jsonfor the official MCP Registry and asmithery.yamlfor Smithery, soagentdraft-mcpcan be listed where developers shop for agent tooling rather than only found by name on PyPI. - Added
agentdraft-mcpnow has a public source repository at ryabinski-labs/agentdraft-mcp. The MCP registry, Smithery, PulseMCP and Glama all resolve a server through a public GitHub repo, and AgentDraft's application repo is private — so the server's directory is published as a mirror. ItsRepositorylink on PyPI now opens, and you can read the code before you install it. - Fixed
Structured data on every page and blog post listed a
github.com/ryabinski-labs/agentdraft-engine-referencerepository that returns 404, and linked an npm organization page instead of the package. Both are corrected.
- Changed
Sixteen blog posts step out of the way of the homepage
- Fixed
Searching for
agentdraftreturned a blog post about AI adoption trends, with agentdraft.io itself nowhere on the first page. 125 posts share one domain and the ones written for an executive audience were outranking the product they were meant to sell. Sixteen posts — thirteen written for a buyer rather than a builder, three about capabilities AgentDraft doesn't ship — now carrynoindex, followand are left out of the sitemap. They stay published, stay linked from/blog, and keep passing link equity onward; they just stop competing with the pages a developer is actually looking for. - Changed
The
noindexdirective can now befollowas well asnofollow, so a page can be withheld from search without also cutting off the links it sends to the rest of the site. Private app routes are unaffected and still emitnoindex, nofollow.
- Fixed
Older releases
- Analytics stops following you past the marketing site
- Blog ingest accepts updates and deletes, not just creates
- One redirect path for a stored paid-tier signup
- Free tier now representable in the billing client
- Free tier can now run multiple agents
- Retired marketing URLs now resolve cleanly
- Approvals — a human sign-off gate for any agent action
- Cookieless marketing analytics goes live
- Answer-engine polish and a shorter path to an API key
- The blog claim guard checks claims, not keywords
- No more dead citation links on the blog
- Every published blog post is back in the sitemap
- Answer-engine remediation pass
- DNSCove authoritative DNS cutover
- Blog ingest API returns the real post URL
- Free calendar collision audit, right from the comparison pages
- Try the API with no signup
- Instant API key, plus a code fallback for magic links
- A faster path from CTA to API key
- Alternatives guides, glossary expansion, and benchmark census
- Trust pages, SEO metadata, and production API tuning
- Billing correctness and an open-source collision benchmark
- A guided setup checklist and a clearer, more accessible dashboard
- Send feedback from the dashboard, plus blog & security SEO fixes
- Checkout now collects tax and accepts promo codes
- Calendar list no longer breaks after disconnecting a feed
- Webmail calendar connector is now Folio
- Calendar connect surfaces real errors; local dev boots again
- Billing webhook resolves the correct plan
- Private app routes are easier for crawlers to retire
- Google user data disclosures
- Launch-readiness proof is easier to audit
- Dashboard sessions last through the workday
- Publish and webhook setup feedback is clearer
- Mailbox webhooks can target one agent
- Email-flow monitoring with AgentDraft mailboxes
- Block out your vacations
- Counter-proposals documented, plus API reference fixes
- Webhooks are now documented
- Booking notes and the video link now land on the calendar event
- The timezone picker is now searchable
- Set your timezone — the one that actually gates bookings
- SDKs speak title, invitee, and timezone
- Scheduling rules are actually enforced
- Working hours read in your own timezone
- Pricing answers its own questions
- Bookings know who they're for
- One canonical URL per marketing page
- Connected calendars resync themselves
- The glossary doubles in size
- Integration pages for n8n and the OpenAI Agents SDK
- A sharper share card and a more legible masthead
- The free Developer tier reaches the homepage
- A free Developer tier, a mobile nav, and a clearer homepage
- Blog posts published via the ingestion API render cleanly
- Recurring ICS events with a non-UTC UNTIL now expand fully
- Permanently delete revoked agents
- Lowercase-safe agent mailbox routing
- Mid-run human consent for high-impact agent actions
- Marketing claim audit and pricing copy alignment
- Conferencing links, Calendar Audit, ChatGPT App, coordination-layer pillar
- Dashboard Webhooks page
- P1 differentiation moat — multi-agent negotiation + OSS engine reference
- P0 distribution oxygen — A2A protocol, two more /vs pages, Vercel AI + Mastra adapters, Claude skill
- Footer composition + Field notes in masthead nav
- Launch wave 1 — collision benchmark, vs/temporal-cortex, newsletter capture
- SEO landing pages + outbound mail fix
- Launch-week polish
- Passkeys
- A real changelog
- Launch readiness — SDKs, packages, and discovery
- Calendar connectors, agent key lifecycle, mailbox API
- Agent mailboxes, onboarding, dashboard hardening
- Production architecture and deploy pipeline
- Initial AgentDraft platform
Frequently asked
What gets a changelog entry?
Anything users or agent builders can observe — new endpoints, breaking changes, dashboard UX, fixed bugs, security patches, infrastructure work that touches the public plane. Internal-only refactors and tests opt out with the skip-changelog label. CI fails any other PR that doesn't touch this changelog file.
How do per-release permalinks work?
Releases that ship a new SDK version get a dedicated /changelog/<slug> permalink with a short summary, version chips, and SoftwareApplication JSON-LD. In-page anchors stay reachable at #r-<date> for releases without a permalink — if multiple un-slugged releases share a date, the second and later get a numeric suffix.