In partnership with

Auth.MD (WorkOS, MIT, github.com/workos/auth.md) is a proposed open protocol that fixes this by hosting a Markdown file at your domain that tells agents exactly how to register users, which flows are supported, what scopes exist, and how to get credentials, without any human touching a sign-up form and without any WorkOS dependency to implement it.

SnackOnAI Engineering | Senior AI Systems Researcher | Technical Deep Dive | June 22, 2026

OAuth 2.0 was built on one foundational assumption: the client accurately represents the intent of the user who authorized it. When you click "Allow" on a third-party app's permission screen, the token that gets issued carries exactly the scopes you approved, and the app is expected to use it for exactly the purpose you authorized. The model works because the client is deterministic: a well-written app has fixed code paths and cannot spontaneously decide to request new capabilities.

AI agents break this assumption in every direction simultaneously. An LLM-based agent is non-deterministic by design. It can be prompt-injected to request elevated privileges. In a multi-agent system, multiple agents can share a single OAuth credential set, making accountability impossible. The agent executing an API call is not the same entity as the user who established intent. And critically, for an agent to even get a credential to use, it has to go through the same sign-up flow a human would, complete with CAPTCHAs, email verification, and form fields.

Auth.MD addresses the last problem directly: giving agents a standardized, machine-readable way to register for services. The broader research literature, OIDC-A (arXiv:2509.25974), Agentic JWT (arXiv:2509.13597), and AgentDID (arXiv:2604.25189, ICDCS 2026), addresses the trust, delegation, and intent problems. These are related but separable layers, and this newsletter covers all four.

Scope: auth.md's two-flow protocol design, the AUTH.MD file format, the ID-JAG assertion mechanism, and how OIDC-A, Agentic JWT, and AgentDID each approach a different layer of the agent identity stack. Not covered: enterprise certificate-based agent attestation (TEE attestation profiles in Agentic JWT), or decentralized identity infrastructure for AgentDID beyond its role as academic context.

What It Actually Does

Auth.MD is three things:

  1. A file format: a Markdown file with YAML-like frontmatter hosted at https://yourapp.com/auth.md

  2. A discovery protocol: agents HTTP GET that URL to find registration instructions

  3. A two-flow registration protocol: the file specifies which flows the service accepts

The analogy to robots.txt is precise and intentional. Just as a web crawler fetches /robots.txt to understand crawl permissions before indexing a site, an AI agent fetches /auth.md to understand registration capabilities before acting for a user on a service.

Early adopters (as of June 2026): Cloudflare (cloudflare.com/auth.md), Firecrawl (firecrawl.dev/auth.md), Resend (resend.com/auth.md), Monday.com (monday.com/auth.md), Rize.io, and others.

Three roles in the protocol:

Role

What it does

Agent

Acts on behalf of a user; reads auth.md and initiates registration

Agent Provider

Vouches for user identity by minting ID-JAGs (Identity Assertion JWTs)

Service

Reads auth.md responses, accepts ID-JAGs or runs OTP flow, issues access tokens

Two flows:

Flow

When used

Human in loop?

Agent Verified

Agent Provider vouches for user via signed ID-JAG

No

User Claimed

No Agent Provider or ID-JAGs not supported; agent shows user an OTP code

Yes (one confirmation)

The output in both cases is a scoped, short-lived access token tied to the user, issued over standard OAuth. The agent gets credentials without the user filling out a form. The service gets a credential scoped to exactly what the agent requested.

The Architecture, Unpacked

Focus on the two-flow fallback design. Most services will support both flows and let the agent pick. If the agent's platform (Claude, GPT, a custom agent framework) is a registered Agent Provider and supports ID-JAGs, the verified flow runs with zero human interaction. If not, the claimed flow gives users one confirmation step. This graceful degradation is what makes the protocol adoptable without requiring the entire ecosystem to upgrade simultaneously.

The Code, Annotated

Snippet One: The AUTH.MD File Format and Discovery

<!-- 
  Example auth.md file hosted at https://yourapp.com/auth.md
  Source: workos/auth.md protocol spec (MIT)
  This file is the machine-readable "entry point" for agents registering users
-->

---
# YAML frontmatter: structured metadata for programmatic parsing
# ← The agent reads this to understand: can I register here? how? what scopes?
name: "Your Notes App"
description: "A collaborative note-taking application"
version: "1.0"

flows:
  # ← THIS is the critical declaration: which registration methods do you support?
  # "verified" = accept ID-JAGs from trusted agent providers (no human in loop)
  # "claimed"  = run OTP flow (requires one user confirmation action)
  - verified
  - claimed

scopes:
  # ← Explicitly declare what an agent can request access to
  # Agents CANNOT request scopes not listed here
  - name: "notes:read"
    description: "Read user's notes"
  - name: "notes:write"
    description: "Create and edit notes"
  - name: "notes:delete"
    description: "Delete notes (requires explicit user consent)"
    requires_confirmation: true  # ← extra safety for destructive ops

endpoints:
  registration: "https://yourapp.com/api/agent/register"
  id_jag_verification: "https://yourapp.com/api/agent/verify-jag"
  # ← Service advertises WHERE to send assertions, not just THAT it accepts them
  
  # For "claimed" flow:
  claim_initiation: "https://yourapp.com/api/agent/claim/start"
  claim_confirmation_url: "https://yourapp.com/claim"  # user visits this

trusted_providers:
  # ← Allowlist of Agent Providers whose ID-JAGs this service will accept
  # ← THIS is the trust anchor: you only verify JWTs from providers you trust
  - "https://authkit.workos.com"
  - "https://your-enterprise-idp.com"
  # ← Without this list, the verified flow would be trivially spoofable
  # (anyone could claim to be an agent provider and mint fake ID-JAGs)
---

# Notes App Agent Integration

Welcome, agent. Follow these instructions to register on behalf of a user.

<!-- 
  The prose section BELOW the frontmatter is human-readable documentation
  that also helps agents understand context and expected behavior.
  This is intentional: the same file serves both machine parsing and
  human developer reading.
-->

## Quick Start
...

The trusted_providers list is the security primitive that makes the agent-verified flow non-trivially spoofable. Without an allowlist, any malicious party could spin up an "agent provider," mint fake ID-JAGs, and use them to register fraudulent accounts on services that accept the verified flow. The trust model is: you trust specific providers, not the protocol in the abstract. This is exactly how Certificate Authorities work for TLS.

Snippet Two: Agent-Side Registration Implementation

# Auth.MD agent-side registration implementation
# Reconstructed from workos/auth.md reference implementation (MIT)
# Covers both flows with design-intent annotations

import httpx
import json
from dataclasses import dataclass
from typing import Optional

@dataclass
class AuthMDConfig:
    """Parsed AUTH.MD file from a target service."""
    name: str
    flows: list[str]          # ["verified", "claimed"] or subset
    registration_endpoint: str
    id_jag_verification_endpoint: str
    claim_initiation_endpoint: str
    trusted_scopes: list[dict]


async def discover_auth_md(service_domain: str) -> Optional[AuthMDConfig]:
    """
    Step 1: Discovery via HTTP GET at /{domain}/auth.md
    ← This is the robots.txt pattern: agents check BEFORE attempting registration
    ← If the file doesn't exist or the domain doesn't support auth.md,
      the agent knows to fall back to other methods (or fail gracefully)
    """
    url = f"https://{service_domain}/auth.md"
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        if response.status_code != 200:
            return None   # service does not support auth.md

    # Parse YAML frontmatter from the Markdown file
    config = parse_auth_md_frontmatter(response.text)
    return config


async def register_verified_flow(
    config: AuthMDConfig,
    agent_provider_url: str,
    user_id: str,
    requested_scopes: list[str],
) -> str:
    """
    Flow A: Agent Verified (no human in loop)
    
    ← The agent asks its OWN identity provider (the Agent Provider) to
      vouch for the user by minting an ID-JAG (Identity Assertion JWT).
    ← The ID-JAG is signed by the Agent Provider and claims:
      "This agent is acting for user X, who is authenticated with us"
    ← The service validates the ID-JAG signature against its trusted_providers
      list and issues a scoped access token WITHOUT any human interaction.
    """
    if "verified" not in config.flows:
        raise ValueError("Service does not support agent-verified flow")

    # Step 1: Request ID-JAG from our agent provider
    # ← The agent provider knows who the user is (they're logged in to the
    #   agent platform, or have pre-authorized the provider to vouch for them)
    id_jag_response = await request_id_jag(
        agent_provider_url=agent_provider_url,
        target_service=config.registration_endpoint,
        user_id=user_id,
        requested_scopes=requested_scopes,
    )
    id_jag = id_jag_response["id_jag"]  # Signed JWT from our provider

    # Step 2: Present ID-JAG to the service's registration endpoint
    # ← THIS is the trick: the service validates the JWT signature against
    #   its trusted_providers list and creates a scoped account without
    #   any form, CAPTCHA, or email verification
    async with httpx.AsyncClient() as client:
        response = await client.post(
            config.registration_endpoint,
            json={
                "flow": "verified",
                "id_jag": id_jag,
                "scopes": requested_scopes,
            }
        )
    result = response.json()
    return result["access_token"]   # Scoped token tied to the real user


async def register_claimed_flow(
    config: AuthMDConfig,
    requested_scopes: list[str],
    show_code_to_user,  # callback to display OTP code in agent UI
) -> str:
    """
    Flow B: User Claimed (OTP fallback)
    
    ← Use when: no Agent Provider available, or service doesn't trust our provider
    ← Requires ONE user action: they see a code and confirm it on the service website
    ← The agent cannot forge this: the user must visit the service's claim URL
      and authenticate with their own account there
    ← This is the trust anchor when cryptographic attestation isn't available:
      proof-of-account-possession by the human user
    """
    if "claimed" not in config.flows:
        raise ValueError("Service does not support user-claimed flow")

    # Step 1: Initiate the claim, get a short-lived code
    async with httpx.AsyncClient() as client:
        response = await client.post(
            config.claim_initiation_endpoint,
            json={"scopes": requested_scopes}
        )
    claim_data = response.json()
    claim_code = claim_data["claim_code"]      # e.g., "ABC-7291"
    claim_url = claim_data["claim_url"]         # user visits this
    poll_token = claim_data["poll_token"]       # for checking status

    # Step 2: Show code to user through whatever UI the agent has
    await show_code_to_user(
        code=claim_code,
        message=f"Please visit {claim_url} and enter this code to authorize access.",
        expiry_seconds=300,   # code typically expires in 5 minutes
    )

    # Step 3: Poll until user confirms (or timeout)
    # ← The service won't issue a token until the user actually
    #   visits the URL, signs in, and enters/confirms the code
    import asyncio
    for _ in range(60):   # poll for up to 5 minutes at 5-second intervals
        await asyncio.sleep(5)
        async with httpx.AsyncClient() as client:
            status_response = await client.get(
                f"{config.claim_initiation_endpoint}/status",
                params={"poll_token": poll_token}
            )
        status = status_response.json()
        if status["state"] == "confirmed":
            return status["access_token"]
        elif status["state"] == "expired":
            raise TimeoutError("User did not confirm within the time limit")

    raise TimeoutError("Polling timed out")

The show_code_to_user callback in the claimed flow is the correct inversion of control. The agent cannot control what happens at the service's claim URL: the user must visit it, authenticate with their own credentials, and explicitly confirm. The agent's only job is to display the code. The trust model is: the user proves account ownership to the service independently of what the agent says or does.

It In Action: End-to-End Worked Example

Task: A coding agent (Claude Code, Cursor, etc.) needs to register the developer for Resend's email API to add transactional email to the project being built.

Step 1: Discovery

GET https://resend.com/auth.md

Response: AUTH.MD file containing:
  flows: [verified, claimed]
  scopes: [emails:send, domains:read, api_keys:manage]
  registration_endpoint: https://resend.com/api/agent/register
  trusted_providers: [https://authkit.workos.com, https://anthropic.com/agent-provider]
  claim_confirmation_url: https://resend.com/claim

Step 2: Agent determines which flow to use

Agent checks: is my agent platform in Resend's trusted_providers list?

Case A: Agent running in Claude Code (Anthropic is in trusted_providers)
  → Use VERIFIED FLOW (agent provider supports ID-JAGs)

Case B: Agent running in a custom OpenCode setup (not in trusted_providers)
  → Use CLAIMED FLOW (OTP fallback)

Step 3A: Agent Verified Flow (Claude Code example)

1. Agent → Anthropic Agent Provider:
   "Mint me an ID-JAG for user [email protected], scoped to resend.com, 
    requesting scopes: [emails:send, domains:read]"

2. Anthropic Agent Provider → Agent:
   {
     "id_jag": "eyJhbGci...",  // Signed JWT
     // Decoded claims:
     // { sub: "[email protected]",
     //   iss: "https://anthropic.com/agent-provider",
     //   aud: "https://resend.com",
     //   agent_id: "claude-code-session-abc123",
     //   scopes: ["emails:send", "domains:read"],
     //   exp: <15 minutes from now> }
   }

3. Agent → Resend /api/agent/register:
   { "flow": "verified", "id_jag": "eyJhbGci...", "scopes": ["emails:send"] }

4. Resend validates:
   - JWT signature verifies against Anthropic's JWKS endpoint ✓
   - Anthropic is in trusted_providers list ✓
   - Requested scopes are subset of scopes in ID-JAG ✓
   - ID-JAG not expired ✓

5. Resend → Agent:
   { "access_token": "re_live_xxx", "user": "[email protected]",
     "scopes": ["emails:send"], "expires_in": 3600 }

Total time: ~400ms (1 Provider request + 1 Service request)
Human interactions: zero

Step 3B: User Claimed Flow (custom agent example)

1. Agent → Resend /api/agent/claim/start:
   { "scopes": ["emails:send"] }

2. Resend → Agent:
   { "claim_code": "FST-4829",
     "claim_url": "https://resend.com/claim?token=xyz",
     "poll_token": "poll_abc", "expires_in": 300 }

3. Agent displays to user:
   "Resend needs your authorization. Visit resend.com/claim 
    and enter code: FST-4829"

4. User visits resend.com/claim, signs in with their Resend account,
   enters FST-4829, clicks "Allow"
   → Resend associates claim code with [email protected]'s account

5. Agent polls GET /api/agent/claim/status?poll_token=poll_abc
   Response (after user confirms): 
   { "state": "confirmed", "access_token": "re_live_yyy",
     "user": "[email protected]", "scopes": ["emails:send"] }

Total time: ~2-5 minutes (depends on user response time)
Human interactions: one (visit URL and enter code)

Why This Design Works, and What It Trades Away

The robots.txt pattern for agent discovery is the correct architecture for protocol adoption. It requires zero central registry: any service can publish an auth.md file independently. Any agent can read it without prior coordination. The service maintains full control over which flows it accepts and which providers it trusts. This is why Cloudflare, Firecrawl, and Resend could adopt the protocol before it was even formally published as a standard.

The two-flow design acknowledges that the agent ecosystem is not uniform. Not all agent platforms will be recognized Agent Providers. Not all services will immediately trust any Agent Provider. The claimed flow gives every service and every agent a working path forward regardless of ecosystem maturity. The verified flow rewards platforms that have done the trust-establishment work with a zero-human-interaction path. The graceful degradation from verified to claimed is what makes this deployable in a heterogeneous ecosystem.

The trust model (explicit trusted_providers allowlist) is correct and conservative. Rather than building a public PKI for Agent Providers and trusting any CA-signed assertion, auth.md puts the trust decision back on the service operator. You decide which providers you trust. This is harder to scale globally but eliminates the class of attacks where a rogue Agent Provider mints fake ID-JAGs for arbitrary services.

What auth.md trades away:

It does not solve the privilege escalation problem inside an existing session. Once a credential is issued, there is no protocol-level mechanism for the service to monitor whether the agent is using it within the scope of the original user intent, or whether it has been prompt-injected into requesting capabilities the user did not intend. This is the problem Agentic JWT (arXiv:2509.13597) and OIDC-A (arXiv:2509.25974) address at the token layer, and it requires separate tooling layered on top of auth.md's registration mechanism.

The protocol does not specify what happens when an agent's session is compromised or when a user wants to revoke an agent's access. The access token revocation mechanism depends entirely on the service's existing OAuth infrastructure. Services with good token management (short-lived tokens, refresh tokens with revocation, per-agent token tracking) will handle this well. Services with long-lived static tokens will not. Auth.md does not enforce either pattern.

The trusted_providers list creates an ecosystem entry barrier. A new agent platform that wants to participate in the verified flow must get itself added to the trusted_providers lists of every service it wants to register for. At small scale this is manageable bilaterally. At large scale, a central registry or federated trust mechanism will become necessary, which is precisely the problem OIDC-A was designed to solve.

The Broader Agent Identity Stack

Auth.md solves discovery and registration. Three research papers address the layers above it:

OIDC-A (arXiv:2509.25974): an extension to OpenID Connect Core 1.0 that adds agent-specific claims to the OIDC standard: agent_id, delegation_chain, attestation verification, and capability-based authorization. Backward compatible with existing OAuth 2.0 / OIDC infrastructure. OIDC-A is what ID-JAGs could be formalized as, if the protocol is standardized.

Agentic JWT (A-JWT, arXiv:2509.13597): a dual-token design where every agent action is cryptographically bound to a user intent token. Introduces agent_checksum as a new OAuth grant type, derived from the agent's prompt + tools + configuration as a one-way hash. Implements proof-of-possession keys to prevent replay and in-process impersonation. Python proof-of-concept blocks 100% of modeled threat requests (prompt injection, scope escalation, replay, impersonation) with less than 2ms overhead.

AgentDID (arXiv:2604.25189, ICDCS 2026): decentralized identifiers (DIDs) and verifiable credentials (VCs) for agents that can be instantiated on demand, migrate across platforms, and authenticate without centralized control. The key addition is a challenge-response mechanism that validates an agent's dynamic execution state at interaction time, not just at token issuance. W3C-compliant, demonstrates scalable throughput with concurrent agents.

These four layers, auth.md for discovery/registration, OIDC-A for standardized agent claims, A-JWT for intent binding, and AgentDID for decentralized identity, form a complete stack. They are not competing proposals. Each one addresses a different failure mode in the agent identity problem.

Technical Moats

The robots.txt discovery pattern. Hosting a file at a well-known path with a predictable format and no central registry is an intentionally low barrier to adoption. The technical moat is not in the protocol complexity, which is deliberately minimal, but in the early adopter network: once Cloudflare, Firecrawl, Resend, and Monday.com have published auth.md files, agent developers have immediate motivation to support the discovery step because the return on implementation is proportional to the number of adopters. This is how robots.txt achieved universal adoption: each individual adopter's payoff grew with the total network size.

The ID-JAG trust model. The trusted_providers allowlist is initially a bilateral relationship (service operator adds specific providers they trust), but it creates the foundation for federated trust later. A service that has already written auth.md discovery support and ID-JAG validation needs only to update its trusted_providers list to accept new provider attestations. The switching cost of adopting a new Agent Provider is minimal once the plumbing is in place. This makes the protocol extensible to the decentralized trust models proposed in OIDC-A and AgentDID without requiring a hard fork.

WorkOS as the reference implementation. WorkOS authoring the protocol and providing a reference Agent Provider (AuthKit) gives the protocol the same distribution advantage that Stripe had when it wrote the payment industry's best developer experience. Auth.md is open and WorkOS-independent by design, but WorkOS is the first and most capable implementation path for services that want to become agent-ready quickly. Protocol authorship with reference implementation is a durable competitive position.

Insights

Insight One: Auth.md solves a problem that nobody was talking about as a security problem. The standard conversation in agent security is about prompt injection, privilege escalation, and delegation chains. The equally important but less-discussed problem is: how does the agent get credentials at all before any of those threats can materialize? The current state is that developers hard-code credentials, agents screen-scrape sign-up forms, or users manually complete registration and paste tokens into agent configurations. Auth.md's contribution is making the credential acquisition step a first-class protocol rather than an afterthought bolted onto human-designed UX. Without solving this step, every other layer of the agent security stack (A-JWT, OIDC-A, AgentDID) is building on a foundation that assumes credentials already exist and were obtained cleanly.

Insight Two: The two-flow design acknowledges a fundamental tension in agent authentication that the research papers mostly gloss over: the verified flow (no human in the loop) is only as trustworthy as the Agent Provider. If the agent platform that mints ID-JAGs is compromised, every assertion it has ever issued is suspect. The claimed flow's single OTP confirmation is weaker from an automation standpoint but stronger from a trust standpoint: it requires the actual human user to prove account ownership at the service directly. Services in regulated industries (banking, healthcare, anything with SOC 2 requirements) may prefer the claimed flow even when the verified flow is available, precisely because the human confirmation creates an audit trail that the service controls. The protocol's flexibility here is a feature, not a lack of conviction about which flow is "correct."

Surprising Takeaway

Auth.md's trust model for the verified flow is structurally identical to how TLS certificate trust works, and it will likely evolve the same way. Today, a service operator manually adds specific Agent Providers to its trusted_providers list, just like how early TLS deployments required administrators to manually add CA certificates. The next step, which neither auth.md nor the research papers have fully addressed, is a federated trust hierarchy where a small number of root Agent Provider Authorities can vouch for downstream Agent Providers, which in turn vouch for specific agents acting for specific users. This is exactly the CA hierarchy that governs TLS trust today. The agent identity ecosystem is, in 2026, at approximately the same maturity level as web PKI was in 1995: the right primitives exist, the bilateral trust relationships are being established, and the federated hierarchy has not yet been built. The team that builds the Agent Certificate Authority gets a structurally powerful position in the ecosystem, and auth.md is the protocol they would build it on.

TL;DR For Engineers

  • Auth.md (workos/auth.md, MIT) is a file hosted at https://yourapp.com/auth.md that tells agents how to register users without a sign-up form. Two flows: Agent Verified (Agent Provider mints a signed ID-JAG, zero human interaction) and User Claimed (OTP fallback, one user confirmation). Output: scoped short-lived OAuth access token. Early adopters: Cloudflare, Firecrawl, Resend, Monday.com.

  • The trusted_providers list in auth.md is the security primitive for the verified flow: you only accept ID-JAGs from providers you explicitly trust. Without this, the verified flow is spoofable. With it, it functions like TLS with explicit CA allowlisting.

  • The broader agent identity stack: OIDC-A (arXiv:2509.25974) extends OIDC with agent claims and delegation chains, backward compatible with OAuth 2.0. Agentic JWT (arXiv:2509.13597) binds agent actions to cryptographically verified user intent using agent_checksum grant type, <2ms overhead, blocks 100% of modeled threats. AgentDID (arXiv:2604.25189, ICDCS 2026) uses W3C DIDs and VCs for decentralized agent identity with challenge-response execution state verification.

  • The problem auth.md does NOT solve: what happens after credentials are issued. Privilege escalation, prompt injection using the issued token, and intent drift are handled by A-JWT and OIDC-A, not by registration-time auth.md. These are complementary, not competing.

  • The ecosystem trajectory: auth.md is building the bilateral trust relationships that will eventually need a federated hierarchy. The trusted_providers allowlist today is where TLS was with manual CA certificates in 1995.

The Sign-Up Form Was Never Designed for Agents

Auth.md's contribution is making explicit what has been an implicit failure mode in every agentic system: the credential acquisition step was assumed to be solved (by humans pasting tokens) when it was never actually solved. A protocol that lets an agent register for a service on behalf of a user, with appropriate authorization and user control, is a necessary primitive for any production agentic system.

The research stack around agent identity (OIDC-A, Agentic JWT, AgentDID) is solving the harder problems of trust, delegation, and intent verification. Auth.md is solving the prerequisite: getting a credential that the agent can use in the first place. Without the prerequisite, the harder problems are moot.

References

Auth.md (WorkOS, MIT, github.com/workos/auth.md) is an open protocol where services host a Markdown file at /auth.md that tells agents how to register users without sign-up forms: two flows (Agent Verified via signed ID-JAGs from trusted Agent Providers with zero human interaction, and User Claimed via OTP with one confirmation step), producing scoped short-lived OAuth access tokens. The trusted_providers allowlist is the security primitive for the verified flow, functioning like explicit CA trust in TLS. The broader agent identity research stack layers on top: OIDC-A (arXiv:2509.25974) extends OIDC with agent claims and delegation chains; Agentic JWT (arXiv:2509.13597) cryptographically binds agent actions to user intent via agent_checksum grant type with <2ms overhead and 100% threat blocking; AgentDID (arXiv:2604.25189, ICDCS 2026) provides W3C-compliant decentralized agent identity with challenge-response execution state verification. Together these address all four layers of the agent identity problem: discovery/registration, standardized claims, intent binding, and decentralized identity.

Sponsored Ad

If you enjoy practical AI insights, check out SnackOnAI and support the newsletter by subscribing, sharing, and exploring our sponsored ad — it helps us keep building and delivering value 🚀

The ones showing up in LLMs convert 3× better than Google

They optimized for LLMs, not just Google.

FAQs. Comparison pages. Transparent pricing. LinkedIn presence. These aren't vanity plays. They're what gets you cited in ChatGPT, Gemini, and Claude when your buyers are researching, your investors are looking, and your future hires are deciding where to work.

Download the free AEO Playbook for Startups from HubSpot and get the exact checklist. Five minutes to read.

Recommended for you