Bird (ex-SparkPost)
bird.com/email-api
96Score 96 out of 100/100
An AI agent's path through Bird (ex-SparkPost)
- FindCan an agent get in and find what it needs?100/100
5 of 5 pass
- ReadCan it read what it finds?100/100
13 of 13 pass
- ActCan it do something with your product?Weakest step90/100
11 of 13 pass · 2 gaps
GoalAn agent uses Bird (ex-SparkPost)
Wider segments are worth more points. The overall adds up every check's points, so it isn't the average of the three parts.
Easy to find, read and use.
Bird (ex-SparkPost) passes every Find check, every Read check and 11 of 13 Act checks. The weakest step is Act (Install shown for four languages). One more fails there, but we'd skip it for now.
The pages marketing owns pass. What's left sits with engineering and product.
- Rank
- =2 of 15 · Email APIsjoint 2nd of 15 Email APIsOn our 9 Nov 2026 scan
- Checks passed
- 29 of 31 counted
- This scan
From our 9 Nov 2026 scan.
Board results come from one dated scan, so every company is compared on the same day. A live scan reads the site as it is now.
- Details
Domain-level checks read bird.com, which hosts Bird (ex-SparkPost).
1What to fixPart 1 of 4
1 gap to fix
Most points for the least effort. Each sits next to the file the best email API on our board shipped, as of 9 Nov 2026. One more check fails with no example to follow yet; it's below the fixes.
All 31 checks29 pass · 2 fail
Find
Read
- ✓Readable without JavaScript (AR-READ-01), Pass12 of 15 pass
- ✓Docs readable without a login (LG-READ-01), PassPass
- ✓Real 404s (AR-READ-02), Pass15 of 15 pass
- ✓llms.txt (AR-READ-07), Pass14 of 15 pass
- ✓llms.txt links work, and it fits (LG-READ-02), PassPass
- ✓Docs pages fit an agent's context (LG-READ-04), PassPass
- ✓Meta description (AR-READ-03), Pass15 of 15 pass
- ✓Structured docs page (AR-READ-04), Pass13 of 15 pass
- ✓Code samples say their language (AR-READ-05), Pass13 of 15 pass
- ✓Readable pricing (AR-READ-11), Pass15 of 15 pass
- ✓Docs in Markdown (LG-READ-03), PassPass
- ✓Structured data (AR-READ-08), Pass13 of 15 pass
- ✓Machine-readable discovery file (AR-READ-06), Pass8 of 15 pass
Act
- ✓MCP server or CLI (AR-ACT-10), Pass12 of 15 pass
- ✓OpenAPI spec (AR-ACT-02), Pass11 of 15 pass
- ✓npm and PyPI packages (AR-ACT-06), Pass11 of 15 pass
- ✓Auth an agent can follow (proxy) (AR-ACT-01), Pass12 of 15 pass
- ✓Every operation has an operationId (LG-ACT-01), PassPass
- ✓MCP server (AR-ACT-03), Pass14 of 15 pass
- ✓Errors have a schema (LG-ACT-02), PassPass
- ×Tools for browser agents (AR-ACT-07), Fail0 of 15 pass
- ✓An agent skill is published (LG-ACT-03), PassPass
- ✓Sign-in an MCP client can use (LG-ACT-04), PassPass
Fix 1: We didn't find an install for Java on the 6 pages we read (TypeScript/JavaScript, Python and Go found)
Do this: Show an install for each language on your SDK page, with your real packages: npm install, pip install, go get, and a Maven <artifactId> or a Gradle implementation line.
×FailWhat we read on Bird (ex-SparkPost) (6)
- GEThttps://bird.com/llms.txtHTTP 200llms.txt: no install shown for Java
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: no install shown for Java
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200quickstart page: no install shown for Java
6 more
- GEThttps://bird.com/docs/sdks/pythonHTTP 200language page: no install shown for Java
- GEThttps://bird.com/docs/sdks/goHTTP 200language page: no install shown for Java
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200MCP page: no install shown for Java
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200quickstart page: TypeScript/JavaScript "npm install @messagebird/sdk"
- GEThttps://bird.com/docs/sdks/pythonHTTP 200language page: Python "pip install messagebird-sdk"
- GEThttps://bird.com/docs/sdks/goHTTP 200language page: Go "go get github.com/messagebird/bird-sdk-go"
✓PassFrom Mailtrap, on our email API board, as of 9 Nov 2026
- GEThttps://docs.mailtrap.io/developersHTTP 200docs page: TypeScript/JavaScript "npm install mailtrap"
- GEThttps://docs.mailtrap.io/developersHTTP 200docs page: Python "pip install mailtrap"
- GEThttps://docs.mailtrap.io/developersHTTP 200docs page: Go "go get github.com/mailtrap/mailtrap-go"
- GEThttps://docs.mailtrap.io/developersHTTP 200docs page: Java "< artifactId > mailtrap-java </ artifactId >"
What the leader shippedView their file ↗
1TypeScript/JavaScript: npm install mailtrap2Python: pip install mailtrap3Go: go get github.com/mailtrap/mailtrap-go4Java: < artifactId > mailtrap-java </ artifactId >6 of the 15 email APIs on our board pass this: Mailtrap, Resend, SendGrid, Mailgun, Mailjet and 1 more. More examples
Why it might matter
An agent working in one of these languages may not find how to install your library in it.
Our call · Depends on your product.
Cover the languages your users write. If you don't ship one of the four, this one may not be for you.
Our judgement.
How we test this
- On your docs surface we look for an install in each of four languages: TypeScript/JavaScript (npm, yarn, pnpm or bun), Python (pip, poetry or uv), Go (go get) and Java (a Maven <artifactId> or a Gradle implementation line).
- All four must appear.
- This shows how to install, not that a package is official.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
- Ours, not AgentReady's.
1 more fails, with no example yet: Tools for browser agents
Nobody on the board passes our check yet
No email API on our board passes our check on these yet, so there's no example to show.
Tools for browser agents: we found something close
Tools for browser agents: tools your web page offers to AI agents that work in a browser (a proposed standard).
We found document.modelContext and registerTool, with tools named search_docs and get_pricing, in this script on 2 Nov, and your homepage loads it. Our rule reads your homepage's raw HTML and inline scripts, not the scripts it loads. Registering the same tools in an inline script would pass this check.
It costs a point, but it's only worth building if agents need to operate forms on your site. If they do, a browser agent may find no tools to call and have to click through instead.
Don't do it for the score. It's still a proposed standard, and almost nobody on our boards passes our check, though Bird, Postmark and CrewAI load it from a script our check doesn't read. Build it only if agents need to operate forms on your site. Our judgement.
Show every address our checks read
Where our checks looked
Every address our checks read in our 9 Nov 2026 scan, by host. What each check read, not a recording of a visit, so there's no order.
✓ passes on this address alone× fails: select it to open the fix· also read here
bird.com
- /robots.txt200 OK✓AI agents allowed, homepage reachable: Pass
- /email-api200 OK·Our scanner gets in: also read here·llms.txt linked from your pages: also read here·Readable without JavaScript: also read here✓Meta description: Pass✓Structured data: Pass×Tools for browser agents: Fail
- /docs/guides/email/overview200 OK·Our scanner gets in: also read here✓Docs page: Pass·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here✓Structured docs page: Pass·Docs in Markdown: also read here
- /llms.txt200 OK·llms.txt linked from your pages: also read here✓llms.txt: Pass✓llms.txt links work, and it fits: Pass
- /sitemap.xml200 OK✓Sitemap: Pass
- /docs/get-started/send-your-first-email200 OK·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here✓Code samples say their language: Pass·Docs in Markdown: also read here·npm and PyPI packages: also read here
- /docs/sdks/python200 OK·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here·Docs in Markdown: also read here·npm and PyPI packages: also read here
- /docs/sdks/go200 OK·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here·Docs in Markdown: also read here
- /docs/ai/mcp-server200 OK·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here·Docs in Markdown: also read here✓MCP server or CLI: Pass✓MCP server: Pass
- /200 OK·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here·Docs in Markdown: also read here
- /docs200 OK·Readable without JavaScript: also read here·Docs readable without a login: also read here·Docs pages fit an agent's context: also read here·Docs in Markdown: also read here
- /leaderfile-check-404404 · expected, it's a probe✓Real 404s: Pass
- /pricing/email200 OK✓Readable pricing: Pass✓Free tier in emails: Pass
- /.well-known/oauth-authorization-server200 OK·Machine-readable discovery file: also read here✓Auth an agent can follow (proxy): Pass✓Sign-in an MCP client can use: Pass
- /.well-known/oauth-protected-resource404 not found·Machine-readable discovery file: also read here
- /.well-known/openid-configuration404 not found·Machine-readable discovery file: also read here
- /.well-known/api-catalog200 OK·Machine-readable discovery file: also read here
- /.well-known/agent-card.json404 not found·Machine-readable discovery file: also read here
- /openapi.json200 OK✓OpenAPI spec: Pass✓Every operation has an operationId: Pass✓Errors have a schema: Pass✓Send operation in the spec: Pass
- /.well-known/agent-skills/index.json200 OK·An agent skill is published: also read here
- /.well-known/agent-skills/bird-cli.zip200 OK·An agent skill is published: also read here
1 check in red is a fix. Select one to open it.
Want a hand fixing this?
Leave your email and we'll reply about the gaps on bird.com. One reply, no newsletter.
We store your email, this domain and its gaps, to reply. Nothing else. To be removed, email rahulu626@gmail.com
2How it comparesPart 2 of 4
How Bird (ex-SparkPost) compares
Score after each fix
Mailtrap, the leader, at 99ScoreRank
- Nowscore 96rank =2
- +1 fixscore 99rank =1level with Mailtrap
One fix at a time, in the order above. Full scores and ranks on our 9 Nov 2026 board: our maths, not a forecast.
1 gap with a real example to follow.
Find, Read and Act against the other 14 email APIs
Out of 100. On each bar, the light mark is their median and the dark one their best.
YouMedianBest
- Find100100100Find: 100, median 100, best 100.
- Read10094100Read: 100, median 94, best 100.
- Act908296Act: 90, median 82, best 96.
0100
Where Bird (ex-SparkPost) stands
On our board
The 15 email APIs on our board average 88, and the top score is 99.
Neighbours on the board
ScoreVs this site
- Mailtrap99+3
- Resend96=
- Bird (ex-SparkPost)96
- Brevo95−1
- Postmark94−2
Mailtrap is 3 ahead.
Email APIs, our 9 Nov 2026 board. Our maths, not a forecast.
What Bird (ex-SparkPost) does well
One more thing: only 8 of the 15 email APIs on our board pass Machine-readable discovery file. Bird (ex-SparkPost) does.
The checks Bird (ex-SparkPost) passes that are rarest among the 15 email APIs on our board.
- ✓Machine-readable discovery fileAR-READ-06 · 8 of 15 on our board pass this
- ✓OpenAPI specAR-ACT-02 · 11 of 15 on our board pass this
- ✓npm and PyPI packagesAR-ACT-06 · 11 of 15 on our board pass this
Compare Bird (ex-SparkPost) with rivals
3Every checkPart 3 of 4
What these checks can't tell you
- Whether an agent can sign up and get a key. One registry found 30 of 100 developer tools blocked it.
- Whether coding agents write current code for your API. In our small test, a 96 and a 71 came out the same: what we found.
- Whether your bot protection lets an agent in when a person sends one. Check your CDN settings.
- Whether ChatGPT recommends you. That depends on far more than these files.
- What another scanner would give you. They ask different questions and weigh them differently: why the numbers differ.
All 31 checks
29 pass, 2 fail, 0 couldn't check, 0 not counted. The count on each row is how many of the 15 email APIs on our board pass that check.
Find · 5 of 5 pass · 36 of 36 points
✓PassAI agents allowed, homepage reachableAR-FIND-01checked /email-api and /docs/guides/email/overview; none of the user or search agents is blocked10 of 10 points · 15 of 15 pass
10 of 10 points · Gate, worth 10
- GEThttps://bird.com/robots.txtHTTP 200checked /email-api and /docs/guides/email/overview; none of the user or search agents is blocked
What our check kept, up to 60 lines or 6 KB
User-Agent: * Content-Signal: search=yes, ai-input=yes, ai-train=yes Allow: / Disallow: /admin # These sections are an unlisted import of the GitBook corpora. # Disallow normally hides the per-page noindex from crawlers; safe here because # these URLs are new, carry no inbound links, and are in no sitemap — and it is # what keeps the site-wide Content-Signal from inviting AI crawlers into them. # Content-Signal is group-scoped, not per-path, so the per-resource X-Robots-Tag # in next.config.ts is what actually carries "no AI" for these URLs. # The one exception, and it must come before the Disallow below it: the retired # knowledge base is a content-collection served under that same prefix, and its # old /knowledge-base URLs are indexed. A crawler following one through the 301 # has to be able to fetch the page to read its noindex, which a Disallow would # stop it doing, leaving the old entries in the index forever. Allow: /docs/engagement-platform/knowledge-base Allow: /*/docs/engagement-platform/knowledge-base Disallow: /docs/engagement-platform Disallow: /*/docs/engagement-platform Disallow: /docs/connectivity-platform Disallow: /*/docs/connectivity-platform Disallow: /docs/taxi Disallow: /*/docs/taxi Disallow: /docs/pusher Disallow: /*/docs/pusher Disallow: /docs/24sessions Disallow: /*/docs/24sessions Disallow: /docs/24sessions-nl Disallow: /*/docs/24sessions-nl Disallow: /docs/toky Disallow: /*/docs/toky Disallow: /docs/toky-es Disallow: /*/docs/toky-es Disallow: /gitbook-assets Sitemap: https://bird.com/sitemap.xml Sitemap: https://bird.com/video-sitemap.xml Agentmap: https://bird.com/.well-known/ard.jsonHow we test this:
- We read robots.txt and check it doesn't disallow / for the agents that fetch for a user or find sites for AI search: ChatGPT-User, OAI-SearchBot, Claude-User, Claude-SearchBot, Perplexity-User, PerplexityBot (no robots.txt counts as allowed).
- We show blocks on GPTBot (OpenAI model training), not scored; ClaudeBot (Anthropic model training), not scored; Google-Extended (Gemini training and grounding), not scored in v1; CCBot (Common Crawl's open dataset), not scored: blocking them is the site's own call.
- Whether Google-Extended should be scored is a rubric v2 question, and we'll announce it before changing anything.
- Then we fetch your homepage as LeaderfileBot and check it returns 2xx after redirects, with no challenge page.
✓PassOur scanner gets inLG-FIND-01homepage: a real answer (200); docs page: a real answer (200)10 of 10 points
10 of 10 points · Gate, worth 10
- GEThttps://bird.com/email-apiHTTP 200homepage: a real answer (200)
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: a real answer (200)
How we test this:
- We fetch your homepage and your docs page as LeaderfileBot, our own scanner, and check neither answers with a challenge page, or a 401 or 403 that a normal browser gets past.
- One blocked page is a fail; both caps your score at 39.
- Firewalls often let in crawlers they can verify, so ChatGPT or Claude may still get in where our scanner can't.
✓PassDocs pageAR-FIND-02docs page, linked from https://bird.com/email-api7 of 7 points · 15 of 15 pass
7 of 7 points · High, worth 7
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page from our board config, linked from https://bird.com/email-api
How we test this:
- We look for your docs page: the first homepage link to a docs., dev. or developer(s). subdomain of your domain, or to a /docs or /developer(s) path; with none, we try https://docs.<host>/ then https://<host>/docs.
- It passes if that page returns 200.
- Board companies use a docs URL we confirmed by hand.
✓Passllms.txt linked from your pagesLG-FIND-02homepage: a Link header to https://bird.com/llms.txt; an llms.txt with markdown links7 of 7 points
7 of 7 points · High, worth 7
- GEThttps://bird.com/email-apiHTTP 200homepage: a Link header to https://bird.com/llms.txt
- GEThttps://bird.com/llms.txtHTTP 200an llms.txt with markdown links
What our check kept, up to 60 lines or 6 KB
a Link header: https://bird.com/llms.txtHow we test this:
- We read your homepage and your docs page and look for a pointer to an llms.txt: a link to it, a <link> tag, a Link header with rel="llms-txt" or an X-Llms-Txt header, or a line on the page naming /llms.txt.
- It passes when one points at an llms.txt that answers with markdown links.
- AFDocs checks the same (llms-txt-directive).
✓PassSitemapAR-FIND-03sitemap listed in robots.txt, <sitemapindex> root2 of 2 points · 15 of 15 pass
2 of 2 points · Low, worth 2
- GEThttps://bird.com/sitemap.xmlHTTP 200sitemap listed in robots.txt, <sitemapindex> root
What our check kept, up to 60 lines or 6 KB
<?xml version="1.0" encoding="UTF-8"?> <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://bird.com/sitemaps/sitemap/0.xml</loc></sitemap><sitemap><loc>https://bird.com/sitemaps/sitemap/1.xml</loc></sitemap><sitemap><loc>https://bird.com/sitemaps/sitemap/2.xml</loc></sitemap></sitemapindex>How we test this:
- We fetch the Sitemap: URL from robots.txt, else /sitemap.xml, and check it returns 200 with a <urlset> or <sitemapindex> root element.
Read · 13 of 13 pass · 75 of 75 points
✓PassReadable without JavaScriptAR-READ-01homepage: 1497 words in the raw HTML; docs page: 1533 words in the raw HTML; docs surface: 1200 words in the raw HTML; docs surface: 924 words in the raw HTML; docs surface: 1213 words in the raw HTML; docs surface: 3616 words in the raw HTML; linked from the docs page: 1689 words in the raw HTML; linked from the docs page: 608 words in the raw HTML10 of 10 points · 12 of 15 pass
10 of 10 points · Gate, worth 10
- GEThttps://bird.com/email-apiHTTP 200homepage: 1497 words in the raw HTML
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: 1533 words in the raw HTML
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200docs surface: 1200 words in the raw HTML
- GEThttps://bird.com/docs/sdks/pythonHTTP 200docs surface: 924 words in the raw HTML
- GEThttps://bird.com/docs/sdks/goHTTP 200docs surface: 1213 words in the raw HTML
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200docs surface: 3616 words in the raw HTML
- GEThttps://bird.com/HTTP 200linked from the docs page: 1689 words in the raw HTML
- GEThttps://bird.com/docsHTTP 200linked from the docs page: 608 words in the raw HTML
How we test this:
- We count the visible words in the raw HTML (no JavaScript run) of your homepage and your docs page, and check each has at least 150.
- With no docs page found (AR-FIND-02), the homepage is judged alone.
✓PassDocs readable without a loginLG-READ-01docs page: readable without a login; docs surface: readable without a login; linked from the docs page: readable without a login10 of 10 points
10 of 10 points · Gate, worth 10
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: readable without a login
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200docs surface: readable without a login
- GEThttps://bird.com/docs/sdks/pythonHTTP 200docs surface: readable without a login
- GEThttps://bird.com/docs/sdks/goHTTP 200docs surface: readable without a login
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200docs surface: readable without a login
- GEThttps://bird.com/HTTP 200linked from the docs page: readable without a login
- GEThttps://bird.com/docsHTTP 200linked from the docs page: readable without a login
How we test this:
- We read your docs page and up to 7 more docs pages (the ones we read for other checks, then links on your docs page).
- A page fails when it answers 401 or 403 to a normal browser too, redirects to a sign-in page, or is a sign-in form with little else on it.
- A redirect counts as a sign-in when it adds one: a sign-in path the page didn't have, a login subdomain, or an identity provider's site such as Okta's when the page was on another site.
- A sign-up page, one whose title or main heading says sign up or create an account, isn't a login.
- A refusal only to automated readers is our scanner being blocked, not a login.
- A login on your docs page caps your score at 39; across the pages, a share of 25% or less caps it at 39, 50% or less at 59.
✓PassReal 404sAR-READ-02returned 404 for a page that doesn't exist10 of 10 points · 15 of 15 pass
10 of 10 points · Must, worth 10
- GEThttps://bird.com/leaderfile-check-404HTTP 404returned 404 for a page that doesn't exist
How we test this:
- We fetch /leaderfile-check-404, a page that shouldn't exist, and check it returns 404 or 410 after redirects.
- Off the board, if that address refuses automated readers, we try /leaderfile-check-404.html.
✓Passllms.txtAR-READ-07text file with markdown links7 of 7 points · 14 of 15 pass
7 of 7 points · High, worth 7
- GEThttps://bird.com/llms.txtHTTP 200text file with markdown links
What our check kept, up to 60 lines or 6 KB
# Bird > Bird connects customer communications across email, SMS, WhatsApp, Apple > Messages and voice, with verification, lookup, mailboxes, eSIM and realtime > tools. Build with the API, SDKs, CLI or hosted MCP server. ## Check capabilities before integrating - **Email, SMS and WhatsApp**: send messages and inspect their delivery through the developer API. WhatsApp also exposes reads for templates, numbers and aggregate stats. Check the operation reference for supported writes. - **Verify**: create a verification to send a one-time passcode, check the code the user enters, and resend on the next channel through the developer API. Listing and reading verifications is available in the dashboard only. - **Voice**: read call legs through the developer API. Use the Voice and SIP guides to choose a calling integration. - **Receiving, setup and administration**: support varies by product and operation. Read the product guide and discover the available tools before acting. - Use the live MCP tool list and OpenAPI specification to verify operations, authorization, required inputs and response states. ## Start here - [Quickstart](https://bird.com/docs/get-started/send-your-first-email): Create an API key and send your first email - [SMS quickstart](https://bird.com/docs/get-started/send-your-first-sms): Enable a destination, send a built-in template SMS, and read its delivery status - [Verify quickstart](https://bird.com/docs/get-started/verify-your-first-customer): Send a one-time passcode and check the code - Install the CLI: `curl 'https://cli.bird.com/install.sh' | sh`, or with Homebrew: `brew install messagebird/tap/bird` - Connect the hosted MCP: `claude mcp add --transport http bird https://mcp.bird.com`, then authenticate it (OAuth-gated, tools fail without a grant): in Claude Code run `/mcp`, select `bird`, choose Authenticate; headless, `claude mcp login bird`. In Claude, add Bird from the connector directory: https://claude.ai/directory/bird Install Bird in Codex: codex://plugins/plugin_asdk_app_6ac74d2aa37481918759cbb0ea8aa6c6 Or in ChatGPT: https://chatgpt.com/plugins/plugin_asdk_app_6ac74d2aa37481918759cbb0ea8aa6c6 Other hosts: https://bird.com/docs/ai/mcp-server#connect-a-client ## Get help - Stuck or have ideas? `bird platform feedback` (MCP: `platform_feedback`) tells us what to improve; `bird platform support create` (MCP: `platform_support_create`) gets you help when something is broken. `bird platform status` shows Bird's service status. ## For AI agents - [MCP server](https://bird.com/docs/ai/mcp-server): Hosted at mcp.bird.com. OAuth authentication, scoped per workspace, curated task-level tools, destructive operations annotated - [Agent skills (bird-ai plugin)](https://bird.com/docs/ai/agent-skills): Skills + MCP, installed in one step - [CLI for agents](https://bird.com/docs/ai/cli-for-agents): JSON output, semantic exit codes, fewer tokens per operation - [llms-full.txt](https://bird.com/llms-full.txt): English authored guides in one file; generated operation references are available separately ## Machine-readable surfaces - [OpenAPI 3.1 spec](https://bird.com/openapi.json): every public endpoint, schema, and error code. Same file as [/openapi.yaml](https://bird.com/openapi.yaml), and the file the SDKs are generated from - [OAuth 2.0 authorization server metadata](https://platform.bird.com/.well-known/oauth-authorization-server): RFC 8414 discovery, at the issuer itself. Authorization, token, device, revocation, and dynamic client registration endpoints, plus every delegable scope - [Search the docs](https://us1.platform.bird.com/v1/docs/search?q=webhook+signature&limit=3): public GET endpoint; set `q` to your task. Read the matching `markdown_url` and linked references before loading a larger corpus - [Sitemap](https://bird.com/sitemap.xml): Indexable pages by locale - [auth.md](https://bird.com/auth.md): how an agent obtains, uses, and revokes a credential, in prose - Any page as Markdown: append `.md` to its URL, or send `Accept: text/markdown` - Code examples: TypeScript/JavaScript, Python, Go and PHP SDKs; Swift and Kotlin Realtime clients; and CLI, cURL, MCP or shell examples, wherever offered. Follow a Markdown page's `Examples:` links for focused language views such as `.py.md`; the links list the alternatives that page offers. - To select examples within the full page, send `Accept-Language: en-us, python` to choose a named example. Matching examples change in place; other examples and content remain. A preference with no matching example keeps the default. The page URL selects the content locale. ## Learn and practise - [Topic and resource catalog](https://bird.com/content-map.json): Versioned relationships between current products, docs, answers, tools, videos and practice briefsHow we test this:
- We read llms.txt at your site root and, if your docs live on another host, at your docs root, and check one returns 200, isn't HTML and has at least one markdown link.
- Off the board, we also try your docs. host and /docs/llms.txt.
- We read the first 2 MB: a larger file is judged on that part, and the result says "read the first 2 MB; the file is larger".
✓Passllms.txt links work, and it fitsLG-READ-0213,547 characters, 86 links; 12 of 12 we tried resolve7 of 7 points
7 of 7 points · High, worth 7
- GEThttps://bird.com/llms.txtHTTP 20013,547 characters, 86 links; 12 of 12 we tried resolve
How we test this:
- We read the llms.txt AR-READ-07 passes on (the first with markdown links) and fetch up to 12 of its links, spread through the file, two at a time.
- A link is broken when it answers 404 or 410, or its host doesn't exist.
- A 2xx after redirects resolves, and so does an answer like 400, 405 or 406 that shows the address is there (an MCP endpoint answers a plain GET with 405).
- A refusal, a 429 or a server error isn't judged.
- The credit is the share that resolve, halved when the file runs to 50,000 characters or more, and nothing past 100,000: AFDocs' size bands.
- With no llms.txt it isn't counted: AR-READ-07 counts that.
✓PassDocs pages fit an agent's contextLG-READ-04docs page: 10,777 characters of text; docs surface: 9,631 characters of text; docs surface: 6,954 characters of text; docs surface: 9,712 characters of text; docs surface: 24,686 characters of text; linked from the docs page: 11,487 characters of text; linked from the docs page: 3,985 characters of text7 of 7 points
7 of 7 points · High, worth 7
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: 10,777 characters of text
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200docs surface: 9,631 characters of text
- GEThttps://bird.com/docs/sdks/pythonHTTP 200docs surface: 6,954 characters of text
- GEThttps://bird.com/docs/sdks/goHTTP 200docs surface: 9,712 characters of text
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200docs surface: 24,686 characters of text
- GEThttps://bird.com/HTTP 200linked from the docs page: 11,487 characters of text
- GEThttps://bird.com/docsHTTP 200linked from the docs page: 3,985 characters of text
How we test this:
- On each docs page we read (up to 7) we count the characters of visible text in the raw HTML, and of its Markdown copy if it has one, and judge the page by the larger of the two: an agent reading either may be cut off.
- Under 50,000 passes, up to 100,000 is half, more fails: AFDocs' bands, from the limits agents cut pages at.
- The credit is the average across the pages.
✓PassMeta descriptionAR-READ-03has a meta description4 of 4 points · 15 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/email-apiHTTP 200has a meta description
What our check kept, up to 60 lines or 6 KB
<meta name="description" content="Send transactional emails, run marketing campaigns, and handle replies in one place. Reach the inbox reliably and build with the Bird API, SDKs, or MCP."/>How we test this:
- We check your homepage's raw HTML (no JavaScript run) has a non-empty meta description or og:description.
✓PassStructured docs pageAR-READ-045 headings (h1 to h3), 1533 words in the raw HTML4 of 4 points · 13 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/docs/guides/email/overviewHTTP 2005 headings (h1 to h3), 1533 words in the raw HTML
What our check kept, up to 60 lines or 6 KB
<h1>Email overview</h1> <h2>How sending works</h2> <h2>The Email section of the dashboard</h2> <h2>Where each guide fits</h2> <h2>Related resources</h2>How we test this:
- We check your docs page's raw HTML (no JavaScript run) has at least 2 headings (h1 to h3) with text and at least 150 visible words.
- Off the board, a docs page that comes back as markdown counts # to ### lines outside code blocks as its headings.
✓PassCode samples say their languageAR-READ-05quickstart page: a code block with a language tag4 of 4 points · 13 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200quickstart page: a code block with a language tag
What our check kept, up to 60 lines or 6 KB
<code class="text-foreground bg-card rounded-sm border px-1 font-mono wrap-anywhere group-[&]/code-block:rounded-none group-[&]/code-block:border-none group-[&]/code-block:bg-transparent group-[&]/code-block:p-0 group-[&]/code-block:text-inherit language-bash">How we test this:
- On your docs surface, we look for a code block that carries a language tag: language-* or lang-* on <pre> or <code>, code-language-* on any element (a code block's wrapper, say), or a data-language or data-lang attribute.
- In markdown files, a fenced block with a language (```ts) counts.
- If no page shows one, we read the markdown copy each HTML page declares (a <link rel="alternate" type="text/markdown">, or its URL plus .md listed in your llms.txt), since many docs sites add the language label with JavaScript.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
✓PassReadable pricingAR-READ-11raw text shows "Free" next to a month or year4 of 4 points · 15 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/pricing/emailHTTP 200from our board config, linked from https://bird.com/email-api; raw text shows "Free" with a period
What our check kept, up to 60 lines or 6 KB
CLI reference Webhooks MCP Server Integrations Tools Changelog Pricing Log in Get Started Menu Email pricing. Built to grow. Start with the published Free allowance. A paid Email plan adds its monthly deposit to your Bird balance. Email usage is charged from the first send at your applicable rate. Get SHow we test this:
- We fetch the first homepage link with 'pricing' in its path, else /pricing (board companies: a pricing URL we confirmed by hand), and check it returns 200 and its raw text (no JavaScript run) shows a price or 'free' within 80 characters of month, mo, year or yr.
- Off the board, a pricing address that answers with JSON counts when it has a price field.
✓PassDocs in MarkdownLG-READ-03docs page: answers Accept: text/markdown; docs surface: answers Accept: text/markdown; linked from the docs page: answers Accept: text/markdown4 of 4 points
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: answers Accept: text/markdown
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200docs surface: answers Accept: text/markdown
- GEThttps://bird.com/docs/sdks/pythonHTTP 200docs surface: answers Accept: text/markdown
- GEThttps://bird.com/docs/sdks/goHTTP 200docs surface: answers Accept: text/markdown
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200docs surface: answers Accept: text/markdown
- GEThttps://bird.com/HTTP 200linked from the docs page: answers Accept: text/markdown
- GEThttps://bird.com/docsHTTP 200linked from the docs page: answers Accept: text/markdown
What our check kept, up to 60 lines or 6 KB
--- title: "Email overview" description: "Understand how Bird sends and receives email, how delivery progresses after acceptance, and where to configure Email in the dashboard." canonical: "https://bird.com/docs/guides/email/overview" --- # Email overview Send transactional and marketing email through `POST /v1/email/messages`. Use a `bk_{region}_...` key with its matching regional host: `https://us1.platform.bird.com` or `https://eu1.platform.bird.com`. We sign the message with DKIM, deliver it, and report each recipient's outcome. To send something before reading further, the [quickstart](/docs/get-started/send-your-first-email) takes you from an API key to a delivered message. This page covers the model the rest of this section assumes, and points at the guide for each part of it. ## How sending works A send is accepted in one call and delivered asynchronously. `POST /v1/email/messages` validates the payload and sending domain, then returns `202 Accepted` with an `em_` message ID. Read each recipient's outcome through [webhook events](/docs/guides/email/events) or the message endpoints. [Sending email](/docs/guides/email/sending-email) covers the payload, field limits, and response. Two consequences of that model shape the rest of this section. **One message, many recipients, one lifecycle each.** A message to five addresses produces five independent outcomes, and the message-level status you read back is an aggregate over them. Suppression is evaluated the same way: one [suppressed](/docs/guides/email/suppressions) address comes back `rejected` while the other four deliver. **Every message declares why you are sending it.** A [category](/docs/guides/email/categories) of `transactional` or `marketing` decides which suppressions apply to it. Someone who unsubscribed from your newsletter still needs their password reset to arrive, and the category is what tells us the difference. A send can also arrive by another route, or leave later. [SMTP](/docs/guides/email/smtp) accepts submissions from anything that speaks the protocol, and [scheduled sending](/docs/guides/email/scheduled-sending) holds a message until a time you set. ## The Email section of the dashboard Email is one of the channels in the dashboard sidebar. Its pages, in the order they appear: | Page | What it holds | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Onboarding** | A three-step checklist: create an API key, send an email, add your domain. It shows until you have finished it | | **Metrics** | Delivery, open, bounce, and complaint rates over time; see [Email metrics](/docs/guides/email/tracking-and-metrics) | | **Emails** | Every message sent; see the [email log](/docs/guides/email/email-log). Its Receiving tab lists what came in | | **Mailboxes** | Programmable inboxes your code reads and replies from; see [Agent mailboxes](/docs/guides/email/mailboxes) | | **Templates** | Reusable subject and body content, with a draft and published versions; see [Email templates](/docs/guides/email/templates) | | **Domains** | Your sending domains, their DNS records, and live verification status; see [Sending domains](/docs/guides/email/sending-domains) | | **IP Pools** | Dedicated IPs and the pools they sit in; see [Dedicated IPs and pools](/docs/guides/email/dedicated-ips-and-pools) | | **Broadcasts** | One email to a stored audience, with delivery tracked per recipient; see [Broadcasts](/docs/guides/email/broadcasts) | | **Suppressions** | Addresses we do not send to, and why; see [Suppressions](/docs/guides/email/suppressions) | | **Unsubscribe page** | Branding for the hosted page every marketing email links to; see [Unsubscribe links](/docs/guides/email/unsubscribe-links) | | **SMTP** | Connection settings, per-key send defaults, and live connections; see [SMTP](/docs/guides/email/smtp) | | **Inbox Insights** | Inbox placement and sender reputation across mailbox providers; see [Inbox Insights](/docs/guides/email/inbox-insights) | | **Competitive insights** | Panel-derived sending volume, cadence, and engagement for watched brands; see [Competitive Insights](/docs/guides/email/competitive-insights) | Recipients live outside the Email section, in **Contacts** in the sidebar: **All contacts** stores people with typed custom properties (see [Contacts](/docs/guides/email/contacts)), and **Audiences** groups them into the reusable lists a broadcast sends to (see [Audiences](/docs/guides/email/audiences)). ## Where each guide fits **Sending.** [Sending email](/docs/guides/email/sending-email) is the one to read first: it owns the payload every other send path is a variation on. From there, [templates](/docs/guides/email/templates) store content you reuse, [attachments](/docs/guides/email/attachments) add files, [batch sending](/docs/guides/email/sending-bulk) submits up to 100 messages in one request, and [broadcasts](/docs/guides/email/broadcasts) send one email to a whole audience. **Domains and authentication.** [Sending domains](/docs/guides/email/sending-domains) covers registering a domain and getting it verified. [DKIM, SPF, and DMARC](/docs/guides/email/dkim-spf-dmarc) explains what each record proves to a receiving mailbox provider, and [BIMI](/docs/guides/email/bimi) shows your logo beside your messages in email apps that support it. **Reputation.** [SuHow we test this:
- On each docs page we read (up to 7), one Markdown answer with content passes the page: it answers Accept: text/markdown with text/markdown, declares a copy with <link rel="alternate" type="text/markdown"> that returns Markdown, or the address the page lands on, after redirects, ending in .md does (for one ending in a slash, both /page.md and /page/index.md).
- An empty answer doesn't count.
- The credit is the share of pages that pass.
- AFDocs, Cloudflare's isitagentready and is-agentic check it.
✓PassStructured dataAR-READ-08has an application/ld+json block2 of 2 points · 13 of 15 pass
2 of 2 points · Low, worth 2
- GEThttps://bird.com/email-apiHTTP 200has an application/ld+json block
What our check kept, up to 60 lines or 6 KB
{"@context":"https:\u002F\u002Fschema.org","@graph":[{"@type":"Organization","@id":"https:\u002F\u002Fbird.com\u002F#organization","name":"Bird","legalName":"Bird B.V.","alternateName":["MessageBird","SparkPost"],"description":"Reach your customers, wherever they are. Email, SMS, WhatsApp, Apple Messages, and Voice.","url":"https:\u002F\u002Fbird.com","foundingDate":"2011","contactPoint":{"@type":"ContactPoint","contactType":"customer support","email":"support@bird.com","url":"https:\u002F\u002Fbird.com\u002Fhelp\u002Fsupport"},"address":{"@type":"PostalAddress","streetAddress":"Keizersgracht 268","postalCode":"1016 EV","addressLocality":"Amsterdam","addressCountry":"NL"},"logo":"https:\u002F\u002Fbird.com\u002Ffavicon-light.png","sameAs":["https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fbirdhq","https:\u002F\u002Fx.com\u002Fmessagebird","https:\u002F\u002Fwww.instagram.com\u002Fmessagebird","https:\u002F\u002Fgithub.com\u002Fmessagebird","https:\u002F\u002Fwww.youtube.com\u002F@birdHQ","https:\u002F\u002Fwww.ycombinator.com\u002Fcompanies\u002Fbird","https:\u002F\u002Fwww.crunchbase.com\u002Forganization\u002Fmessagebird","https:\u002F\u002Fnl.wikipedia.org\u002Fwiki\u002FBird_(bedrijf)","https:\u002F\u002Fwww.wikidata.org\u002Fwiki\u002FQ106845206","https:\u002F\u002Fwww.capterra.com\u002Fp\u002F160795\u002FBird\u002F","https:\u002F\u002Fwww.g2.com\u002Fproducts\u002Fmessagebird-bird"]},{"@type":"WebSite","@id":"https:\u002F\u002Fbird.com\u002F#website","name":"Bird","url":"https:\u002F\u002Fbird.com","publisher":{"@id":"https:\u002F\u002Fbird.com\u002F#organization"}}]}How we test this:
- We check your homepage's raw HTML has an application/ld+json block that parses as JSON and has @type or @context.
✓PassMachine-readable discovery fileAR-READ-06valid JSON2 of 2 points · 8 of 15 pass
2 of 2 points · Low, worth 2
- GEThttps://bird.com/.well-known/oauth-authorization-serverHTTP 200valid JSON
- GEThttps://bird.com/.well-known/oauth-protected-resourceHTTP 404returned 404
- GEThttps://bird.com/.well-known/openid-configurationHTTP 404returned 404
- GEThttps://bird.com/.well-known/api-catalogHTTP 200valid JSON
- GEThttps://bird.com/.well-known/agent-card.jsonHTTP 404returned 404
What our check kept, up to 60 lines or 6 KB
{"issuer":"https://platform.bird.com","authorization_endpoint":"https://platform.bird.com/v1/oauth/authorize","token_endpoint":"https://platform.bird.com/v1/oauth/token","device_authorization_endpoint":"https://platform.bird.com/v1/oauth/device","revocation_endpoint":"https://platform.bird.com/v1/oauth/revoke","registration_endpoint":"https://platform.bird.com/v1/oauth/register","grant_types_supported":["authorization_code","urn:ietf:params:oauth:grant-type:device_code","refresh_token"],"response_types_supported":["code"],"scopes_supported":["access_restrictions:read","access_restrictions:write","amb:read","amb:write","amb_management:read","amb_management:write","analytics:read","analytics:write","api_keys:read","api_keys:write","assets:read","assets:write","audit:read","audit:write","competitive:read","competitive:write","compliance:read","compliance:write","domains:read","domains:write","email_management:read","email_management:write","email_marketing:read","email_marketing:write","emails:read","emails:write","esim:read","esim:write","esim_credentials:read","esim_credentials:write","inbox_insights:read","inbox_insights:write","ip_pools:read","ip_pools:write","lookup:read","lookup:write","mailbox:read","mailbox:write","mailbox_management:read","mailbox_management:write","members:read","members:write","numbers:read","numbers:write","preferences:read","preferences:write","rcs:read","rcs:write","rcs_management:read","rcs_management:write","realtime:read","realtime:write","request_logs:read","request_logs:write","service_accounts:read","service_accounts:write","sms:read","sms:write","sms_management:read","sms_management:write","trust:read","trust:write","verify:read","verify:write","verify_management:read","verify_management:write","voice:read","voice:write","voice_management:read","voice_management:write","webhooks:read","webhooks:write","whatsapp:read","whatsapp:write","whatsapp_management:read","whatsapp_management:write","workspace:read","workspace:write","org:access_restrictions:read","org:access_restrictions:write","org:audit:read","org:audit:write","org:billing:read","org:billing:write","org:ip_pools:read","org:ip_pools:write","org:members:read","org:members:write","org:settings:read","org:settings:write","org:trust:read","org:trust:write","org:workspaces:read","org:workspaces:write"],"code_challenge_methods_supported":["S256"],"token_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_post"],"revocation_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_post"],"authorization_response_iss_parameter_supported":true}How we test this:
- We fetch five standard .well-known files and check at least one returns 200 with valid JSON: oauth-authorization-server (RFC 8414), oauth-protected-resource (RFC 9728), openid-configuration, api-catalog (RFC 9727) and agent-card.json (A2A).
- This list is ours: AgentReady v2.0 doesn't name one.
- Off the board, on a miss, we also read oauth-protected-resource on the mcp., api. and docs. hosts of your domain, where that metadata usually lives, and it counts only with its resource field.
Act · 11 of 13 pass · 52 of 58 points
✓PassMCP server or CLIAR-ACT-10MCP page: tools email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list; email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list act on the product (AR-ACT-03)10 of 10 points · 12 of 15 pass
10 of 10 points · Must, worth 10
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200MCP page: tools email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list; email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list act on the product (AR-ACT-03)
What our check kept, up to 60 lines or 6 KB
e most tools, because it has the most surface to configure. The other channels carry the same send-and-read shape. Messaging Send and inspect email : email_send , email_send_batch , email_list , and email_get , which returns the message with its aggregate delivery status. Per-recipient delivery statuses and tHow we test this:
- Passes when AR-ACT-03 passes (your docs surface names your own MCP server, not just a mention or a blog post about one; on the board, only an MCP server with a tool that acts on the product: send, manage or query, not only search docs, since AgentReady calls this "the interface an agent acts through"), or when your docs surface shows a CLI install: brew install, npm i -g, npm install -g, pipx install, uv tool install, go install, az extension add, or curl ... | sh (or | bash).
- A mention of MCP that isn't your own server, with no CLI install, isn't counted.
- For board companies, the CLI half counts only a command of the product's own CLI that we confirmed by hand, like az communication email send or twilio email:send, on the pages we read or on the docs page that shows it: an install alone could be any tool (an MCP setup guide installing pnpm, say).
- For a product inside a larger platform, the platform's MCP server or CLI counts when its docs show it covers the product.
- An MCP server earns both this check and AR-ACT-03, because AgentReady lists them as two items.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
✓PassOpenAPI specAR-ACT-02OpenAPI 3.1.0, 391 paths7 of 7 points · 11 of 15 pass
7 of 7 points · High, worth 7
- GEThttps://bird.com/openapi.jsonHTTP 200from our board config, linked from https://bird.com/docs/api; OpenAPI 3.1.0, 391 paths
How we test this:
- We look for an OpenAPI or Swagger document: for board companies, a URL we confirmed by hand; then up to 2 links on your docs surface whose URL mentions openapi or swagger, or whose link text does for a .json or .yaml file (files on other sites count when your docs link them; an address written out in your llms.txt or another text file counts as a link, and its line as the link text); then /openapi.json and /openapi.yaml on your host and your docs host.
- Off the board, a .json or .yaml link under an llms.txt heading that names OpenAPI counts as a link to a spec, or, where that section has none, a link with no file extension, and on a miss we also try those two on the docs., developers. and api. hosts of your domain.
- It passes if one parses as JSON or YAML with an openapi or swagger key and at least one path.
- A spec over 10 MB counts as couldn't check.
✓Passnpm and PyPI packagesAR-ACT-06quickstart page: npm install "npm install @messagebird/sdk"; language page: pip install "pip install messagebird-sdk"7 of 7 points · 11 of 15 pass
7 of 7 points · High, worth 7
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200quickstart page: npm install "npm install @messagebird/sdk"
- GEThttps://bird.com/docs/sdks/pythonHTTP 200language page: pip install "pip install messagebird-sdk"
What our check kept, up to 60 lines or 6 KB
npm install @messagebird/sdk pip install messagebird-sdkHow we test this:
- On your docs surface we look for an npm install (npm, yarn, pnpm or bun) and a pip install (pip, poetry or uv) of a named package.
- Both must appear, on any of the pages (AgentReady: npm and PyPI).
- Off the board, uv tool install and pipx install also count as a pip install.
- Off the board, if one is missing we also read the markdown copy each HTML page declares (a <link rel="alternate" type="text/markdown">, or its URL plus .md listed in your llms.txt), then up to 2 pages your llms.txt names for that language.
- AgentReady v2.0 asks for SDKs and a CLI here; this check tests the npm and PyPI half, and a CLI counts under AR-ACT-10.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
✓PassAuth an agent can follow (proxy)AR-ACT-01OAuth metadata parses, with issuer4 of 4 points · 12 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/.well-known/oauth-authorization-serverHTTP 200OAuth metadata parses, with issuer
What our check kept, up to 60 lines or 6 KB
{"issuer":"https://platform.bird.com","authorization_endpoint":"https://platform.bird.com/v1/oauth/authorize","token_endpoint":"https://platform.bird.com/v1/oauth/token","device_authorization_endpoint":"https://platform.bird.com/v1/oauth/device","revocation_endpoint":"https://platform.bird.com/v1/oauth/revoke","registration_endpoint":"https://platform.bird.com/v1/oauth/register","grant_types_supported":["authorization_code","urn:ietf:params:oauth:grant-type:device_code","refresh_token"],"response_types_supported":["code"],"scopes_supported":["access_restrictions:read","access_restrictions:write","amb:read","amb:write","amb_management:read","amb_management:write","analytics:read","analytics:write","api_keys:read","api_keys:write","assets:read","assets:write","audit:read","audit:write","competitive:read","competitive:write","compliance:read","compliance:write","domains:read","domains:write","email_management:read","email_management:write","email_marketing:read","email_marketing:write","emails:read","emails:write","esim:read","esim:write","esim_credentials:read","esim_credentials:write","inbox_insights:read","inbox_insights:write","ip_pools:read","ip_pools:write","lookup:read","lookup:write","mailbox:read","mailbox:write","mailbox_management:read","mailbox_management:write","members:read","members:write","numbers:read","numbers:write","preferences:read","preferences:write","rcs:read","rcs:write","rcs_management:read","rcs_management:write","realtime:read","realtime:write","request_logs:read","request_logs:write","service_accounts:read","service_accounts:write","sms:read","sms:write","sms_management:read","sms_management:write","trust:read","trust:write","verify:read","verify:write","verify_management:read","verify_management:write","voice:read","voice:write","voice_management:read","voice_management:write","webhooks:read","webhooks:write","whatsapp:read","whatsapp:write","whatsapp_management:read","whatsapp_management:write","workspace:read","workspace:write","org:access_restrictions:read","org:access_restrictions:write","org:audit:read","org:audit:write","org:billing:read","org:billing:write","org:ip_pools:read","org:ip_pools:write","org:members:read","org:members:write","org:settings:read","org:settings:write","org:trust:read","org:trust:write","org:workspaces:read","org:workspaces:write"],"code_challenge_methods_supported":["S256"],"token_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_post"],"revocation_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_post"],"authorization_response_iss_parameter_supported":true}How we test this:
- A stand-in: AgentReady asks for self-serve key generation with documented scopes, or OAuth metadata, and key sign-up can't be tested in code.
- It passes if OAuth metadata parses as JSON with the field its RFC requires (issuer for RFC 8414, resource for RFC 9728), or if your docs say "API key" or "API token" (also inside a placeholder like YOUR_API_KEY) within 200 characters of a documented auth header: an X-...-Key or X-...-Token header, a header named ...-Key or ...-Token, Authorization with Bearer, or "Bearer API key".
- The word "token" on its own doesn't count.
- For board companies we also read the authentication page their docs link.
- Off the board, OAuth metadata with its resource field on your mcp., api. or docs. host also counts.
- A board company whose API signs each request (like AWS Signature Version 4) or takes the key in the request body isn't counted: this stand-in can't judge that kind of auth either way.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
✓PassEvery operation has an operationIdLG-ACT-01529 of 529 operations have an operationId4 of 4 points
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/openapi.jsonHTTP 200529 of 529 operations have an operationId
How we test this:
- In the OpenAPI spec AR-ACT-02 finds, we count the operations with a non-empty operationId.
- The credit is the share that have one.
- With no spec, it isn't counted: AR-ACT-02 already counts that.
✓PassMCP serverAR-ACT-03MCP page: tools email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list; email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list act on the product4 of 4 points · 14 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200MCP page: tools email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list; email_send, email_send_batch, email_list, email_domains_create, email_templates_create, webhooks_list act on the product
What our check kept, up to 60 lines or 6 KB
e most tools, because it has the most surface to configure. The other channels carry the same send-and-read shape. Messaging Send and inspect email : email_send , email_send_batch , email_list , and email_get , which returns the message with its aggregate delivery status. Per-recipient delivery statuses and tHow we test this:
- On your docs surface we look for your own MCP server and quote the line: your name next to "MCP" ("Acme MCP server"), "our" or "official" MCP server, or an mcp.<your domain> address.
- Any other mention of "MCP server" or "Model Context Protocol", like a directory or an explainer, isn't counted: it can't fail you and it earns no points, because we can't tell the server is yours.
- A mention in a link to a blog post, or on an llms.txt line that links to one, doesn't count at all: a post about building a server isn't one you ship.
- For board companies we read the MCP page their docs link and list the tools it documents: a server that only searches your docs counts here, as AgentReady describes an MCP server as a "standard tool protocol for docs search and actions".
- We don't probe /mcp or call any server.
- Off the board, OAuth metadata with its resource field on your mcp. host also counts: it's the server's own file.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
✓PassErrors have a schemaLG-ACT-02529 of 529 operations declare an error response with a schema4 of 4 points
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/openapi.jsonHTTP 200529 of 529 operations declare an error response with a schema
How we test this:
- In the OpenAPI spec AR-ACT-02 finds, we count the operations that declare a 4xx, 5xx or default response with a schema, directly or through a $ref.
- The credit is the share that do.
- We note when they use application/problem+json (RFC 9457), the standard shape.
- With no spec, it isn't counted.
- The IETF's draft agent-friendly API profile, is-agentic and Alpic check it.
×FailTools for browser agentsAR-ACT-07· we found something close0 of 2 points · 0 of 15 pass
Tools for browser agents: we found something close. It costs a point, but it's only worth building if agents need to operate forms on your site. If they do, a browser agent may find no tools to call and have to click through instead.
0 of 2 points · Low, worth 2
- GEThttps://bird.com/email-apiHTTP 200no modelContext in the raw HTML or inline scripts
- GEThttps://bird.com/_next/static/chunks/0y5nm4m2hqbhu.jsHTTP 200We found document.modelContext and registerTool, with tools named search_docs and get_pricing, in this script on 2 Nov, and your homepage loads it. Our rule reads your homepage's raw HTML and inline scripts, not the scripts it loads. Registering the same tools in an inline script would pass this check.
How we test this:
- We check your homepage's raw HTML, inline scripts included, contains modelContext (AgentReady names document.modelContext).
- External scripts aren't fetched.
✓PassAn agent skill is publishedLG-ACT-032 skills listed (bird-cli, email-audit); the first skill, bird-cli, answers; read the first 2 MB; the file is larger2 of 2 points
2 of 2 points · Low, worth 2
- GEThttps://bird.com/.well-known/agent-skills/index.jsonHTTP 2002 skills listed (bird-cli, email-audit)
- GEThttps://bird.com/.well-known/agent-skills/bird-cli.zipHTTP 200the first skill, bird-cli, answers; read the first 2 MB; the file is larger
What our check kept, up to 60 lines or 6 KB
{ "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json", "skills": [ { "name": "bird-cli", "type": "archive", "description": "Use when operating Bird through the bird CLI to preview or send messages, inspect or manage API resources, register or inspect Inbox Insights seed tests, or onboard an account; excludes client development.", "url": "https://bird.com/.well-known/agent-skills/bird-cli.zip", "digest": "sha256:3b5bd4762eb4b82497f20d465867efb453029808df587edded56f23edd15c7e2" }, { "name": "email-audit", "type": "archive", "description": "Use when auditing a live domain's email authentication or spam-delivery problems involving DMARC, SPF, DKIM, BIMI, or MX; single-record drafts use bird validators.", "url": "https://bird.com/.well-known/agent-skills/email-audit.zip", "digest": "sha256:4ff608d8364062a32571c9f6cc2fc2043020adb4aa26e945f9262fd578f8ea80" } ] }How we test this:
- Any of three passes: /.well-known/agent-skills/index.json on your site or your docs (or one a Link header names) lists a skill whose file answers; your docs or llms.txt link a SKILL.md that answers with a name and a description; or your docs show a skills install command, on a page we read or on up to 3 pages your docs or llms.txt link about skills or your CLI.
- An install is npx skills add, claude plugin install, a git clone into a skills folder, or your own command line running plugin install or skills add right after the word skill.
- An index under a folder, like /developer/, may list its files from that folder.
- Cloudflare's isitagentready, agenticplug and Alpic check it.
✓PassSign-in an MCP client can useLG-ACT-04S256, scopes and a way for a client to register2 of 2 points
2 of 2 points · Low, worth 2
- GEThttps://bird.com/.well-known/oauth-authorization-serverHTTP 200S256, scopes and a way for a client to register
What our check kept, up to 60 lines or 6 KB
{"issuer":"https://platform.bird.com","authorization_endpoint":"https://platform.bird.com/v1/oauth/authorize","token_endpoint":"https://platform.bird.com/v1/oauth/token","device_authorization_endpoint":"https://platform.bird.com/v1/oauth/device","revocation_endpoint":"https://platform.bird.com/v1/oauth/revoke","registration_endpoint":"https://platform.bird.com/v1/oauth/register","grant_types_supported":["authorization_code","urn:ietf:params:oauth:grant-type:device_code","refresh_token"],"response_types_supported":["code"],"scopes_supported":["access_restrictions:read","access_restrictions:write","amb:read","amb:write","amb_management:read","amb_management:write","analytics:read","analytics:write","api_keys:read","api_keys:write","assets:read","assets:write","audit:read","audit:write","competitive:read","competitive:write","compliance:read","compliance:write","domains:read","domains:write","email_management:read","email_management:write","email_marketing:read","email_marketing:write","emails:read","emails:write","esim:read","esim:write","esim_credentials:read","esim_credentials:write","inbox_insights:read","inbox_insights:write","ip_pools:read","ip_pools:write","lookup:read","lookup:write","mailbox:read","mailbox:write","mailbox_management:read","mailbox_management:write","members:read","members:write","numbers:read","numbers:write","preferences:read","preferences:write","rcs:read","rcs:write","rcs_management:read","rcs_management:write","realtime:read","realtime:write","request_logs:read","request_logs:write","service_accounts:read","service_accounts:write","sms:read","sms:write","sms_management:read","sms_management:write","trust:read","trust:write","verify:read","verify:write","verify_management:read","verify_management:write","voice:read","voice:write","voice_management:read","voice_management:write","webhooks:read","webhooks:write","whatsapp:read","whatsapp:write","whatsapp_management:read","whatsapp_management:write","workspace:read","workspace:write","org:access_restrictions:read","org:access_restrictions:write","org:audit:read","org:audit:write","org:billing:read","org:billing:write","org:ip_pools:read","org:ip_pools:write","org:members:read","org:members:write","org:settings:read","org:settings:write","org:trust:read","org:trust:write","org:workspaces:read","org:workspaces:write"],"code_challenge_methods_supported":["S256"],"token_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_post"],"revocation_endpoint_auth_methods_supported":["none","client_secret_basic","client_secret_post"],"authorization_response_iss_parameter_supported":true}How we test this:
- We look for OAuth authorization server metadata (RFC 8414): at /.well-known/oauth-authorization-server on your site, through the authorization_servers your protected-resource metadata (RFC 9728) names, and on your mcp. host.
- It passes when it lists S256 in code_challenge_methods_supported, has scopes_supported, and has a registration_endpoint or client_id_metadata_document_supported, as the MCP authorization spec asks.
- With no OAuth metadata, it isn't counted.
×FailInstall shown for four languagesEM-01We didn't find an install for Java on the 6 pages we read (TypeScript/JavaScript, Python and Go found)0 of 4 points · 6 of 15 pass
We didn't find an install for Java on the 6 pages we read (TypeScript/JavaScript, Python and Go found). An agent working in one of these languages may not find how to install your library in it.
0 of 4 points · Medium, worth 4
- GEThttps://bird.com/llms.txtHTTP 200llms.txt: no install shown for Java
- GEThttps://bird.com/docs/guides/email/overviewHTTP 200docs page: no install shown for Java
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200quickstart page: no install shown for Java
- GEThttps://bird.com/docs/sdks/pythonHTTP 200language page: no install shown for Java
- GEThttps://bird.com/docs/sdks/goHTTP 200language page: no install shown for Java
- GEThttps://bird.com/docs/ai/mcp-serverHTTP 200MCP page: no install shown for Java
- GEThttps://bird.com/docs/get-started/send-your-first-emailHTTP 200quickstart page: TypeScript/JavaScript "npm install @messagebird/sdk"
- GEThttps://bird.com/docs/sdks/pythonHTTP 200language page: Python "pip install messagebird-sdk"
- GEThttps://bird.com/docs/sdks/goHTTP 200language page: Go "go get github.com/messagebird/bird-sdk-go"
How we test this:
- On your docs surface we look for an install in each of four languages: TypeScript/JavaScript (npm, yarn, pnpm or bun), Python (pip, poetry or uv), Go (go get) and Java (a Maven <artifactId> or a Gradle implementation line).
- All four must appear.
- This shows how to install, not that a package is official.
- If none of the pages we read is a quickstart or SDK page, a miss isn't counted: it can't fail you or withhold your score.
- Ours, not AgentReady's.
✓PassSend operation in the specEM-02the spec has POST /v1/email/messages, POST /v1/email/batches, POST /v1/email/messages/{message_id}/cancel and 40 more4 of 4 points · 11 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/openapi.jsonHTTP 200the spec has POST /v1/email/messages, POST /v1/email/batches, POST /v1/email/messages/{message_id}/cancel and 40 more
How we test this:
- In the OpenAPI spec AR-ACT-02 found, we look for a POST operation on a path containing mail, email, message or send.
- No spec counts as a fail.
- Ours, not AgentReady's.
✓PassFree tier in emailsEM-03free tier: "1K emails / month"4 of 4 points · 13 of 15 pass
4 of 4 points · Medium, worth 4
- GEThttps://bird.com/pricing/emailHTTP 200from our board config, linked from https://bird.com/email-api; free tier: "1K emails / month"
What our check kept, up to 60 lines or 6 KB
mpare published monthly deposits. Sending rates appear when Bird publishes them for each plan. Select a currency to see available prices. USD Free $0 1K emails / month included Get Started Sending stops at the Free plan limit Startup $15 / month Approx. 37.5K emails / month Get Started Deposit becomes spendable BirdHow we test this:
- On the pricing page AR-READ-11 reads, we look for "free" within 300 characters of a number followed by emails, messages or sends and a period (a month, a day, or 30 days), like "3,000 emails/month" or "4,000 sends in any rolling 30-day window", in the raw text (no JavaScript run).
- A one-time allowance with no period doesn't count.
- Ours, not AgentReady's.
How we check: every check, its points and the thresholds, from the same code that runs the scan.
Something wrong? Report it to rahulu626@gmail.com
4Your next stepsPart 4 of 4
Your next steps
- 1Pick your fixes
- 2Hand them off
- 3Rescan once it's live
- 4Stay ahead of your category
- Then back to 1 when a rival passes you
Pick your fixes
Usually the founder or DevRel lead
One fix takes Bird (ex-SparkPost) from 96 to 99, joint 1st of 15 email APIs, past Resend.
Nothing copied yet from this browser.
Hand them off
To whoever ships it
Fix with AI writes each fix for whoever ships it: your coding agent, an engineer, product or marketing. Open it in Cursor, as a GitHub issue or in Linear, or copy it. Nothing runs until you send it.
Rescan once it's live
Usually the engineer, after the deploy
A rescan reads Bird (ex-SparkPost) again and shows what now passes, the new score and who you passed.
Last scan: 96 on 9 Nov, joint 2nd of 15 email APIs.
Weekly, for 4 weeks. A calendar file: no email from us.Bookmark this page: it opens on our 9 Nov 2026 scan, with a live scan one press away.Stay ahead of your category
DevRel, the founder
Rivals ship too. Watch Bird (ex-SparkPost) with Mailtrap, the nearest on the board: home keeps all three, and Rescan all there shows who moved.
Track it weekly, or scan from your terminal
Scan from your terminal
npx legible-cli bird
Add it for your coding agent
Adds a skill to your project. Ask your agent to use it, and it scans your live site, reads the real file behind each gap and helps write your own. It only publishes if you ask.
npx legible-cli skill
If Windows PowerShell blocks npx, type npx.cmd instead.
Get warned if this slips
A GitHub Action that runs in your own repo, once a week. It fails, naming the check, if something this site passes today stops passing. Each alert links back to the result. Add a Slack webhook as a repo secret named SLACK_WEBHOOK_URL, and a change also posts to your channel; nothing else is sent to us. Anything we can't be sure of only warns. GitHub notifies whoever created the job, depending on their settings. In a public repo, it turns scheduled jobs off after 60 days with no activity.
.github/workflows/legible.yml
1 fix · copy, or open in Cursor, GitHub, Linear