
SendPost exposes a single versioned REST API at https://api.sendpost.io/api/v1, authenticated by scoped header keys rather than OAuth, and backed by 6 officially maintained SDKs. The surface is deliberately narrow, send, templates, domains, stats, suppressions, messages, webhooks, IPs, IP pools and sub-accounts, the primitives an ESP or a high-volume sender wires into a product. On the agent side the verdict is blunt: as of August 2026 there is no official SendPost MCP server and no community wrapper, so any AI-agent integration today is a generic HTTP bridge you build and maintain yourself.
Model Context Protocol is now the default way AI agents call SaaS APIs: the vendor ships a server, the agent discovers typed tools, and the integration stops being bespoke glue. Buyers scoping an agent workflow need to know whether that path exists. For SendPost it does not.
The three places a server would surface are empty: the 43 repositories in the github.com/sendpost organisation hold no MCP project, the docs index at docs.sendpost.io/llms.txt lists no MCP page, and no entry appears in public MCP directories. Agent access means pointing a generic HTTP-to-MCP bridge at https://api.sendpost.io/api/v1 with an X-SubAccount-ApiKey header and owning the tool definitions yourself.
NONE FOUND
Does not exist as of August 2026. No repository, no docs page, no registry listing, nothing in progress. No community or commercial wrapper either.
OFFICIAL
A machine-readable index of the docs. Cheap for an LLM to retrieve and cite, but a discovery file: no tools, no auth, no side effects.
OFFICIAL
The starting point for a do-it-yourself server: feed it to an OpenAPI-to-MCP generator, then trim the tool list to what an agent should touch.
NO APP
No SendPost app on Zapier, the sibling product SendX has one. Automation falls back to the REST API and webhooks.
A missing MCP server is not a dealbreaker for a transactional relay, but it moves cost onto your side. An agent that reads deliverability stats or writes to the suppression list means building and maintaining a bridge: tool schemas, credential scoping, error mapping, and a rate-limit story SendPost does not publish. Raise it during the demo: pricing is quote-based, so it is a negotiable line item.
Conventional JSON over HTTPS, with one structural idea to grasp first: everything is scoped to either an account or a sub-account, and the path segment tells you which. /subaccount/ is the sending plane, email, domains, stats, suppressions, webhooks. /account/ is the control plane, provisioning, dedicated IPs, IP pools. The split exists because SendPost is built for ESPs reselling capacity, where one account fans out into many tenant sub-accounts.
| Base URL | https://api.sendpost.io/api/v1 CURRENT |
| Transport | HTTPS only, JSON request and response bodies |
| Auth style | Custom headers-X-SubAccount-ApiKey or X-Account-ApiKey |
| Scoping | /subaccount/ sending plane · /account/ control plane |
| SMTP relay | smtp.sendpost.io–587/2525/25 STARTTLS, 465 SSL |
| Compatibility layers | SendGrid-shaped and Amazon SES-shaped endpoints for migration |
| Events | Signed webhooks: delivery, open, click, bounce, complaint, unsubscribe |
| Pagination | Query parameters per endpoint; no documented global cursor scheme |
Two things are absent on purpose. SendPost documents no HTTP client timeout, so set your own. And there is no house pagination style: list endpoints take query parameters, but no cursor or link-header contract is published, so page a large suppression list against the OpenAPI specification rather than an assumption. The endpoints that exist are documented well; the cross-cutting conventions are not.
No OAuth flow, no bearer-token convention. Authentication is a raw API key in a custom header, and there are three distinct credential types plus SMTP AUTH. The wrong one returns a bare 401 Unauthorized with no indication of which scope was expected, the most common first-day failure.
The key an application uses at runtime: sending email or a stored template, verifying domains, reading stats, managing suppressions, retrieving a message with its event history, registering webhooks. Scoped to one sub-account, so it is the right credential to hand to a tenant or a single service.
X-SubAccount-ApiKey: your_subaccount_api_key Content-Type: application/json
Account-scoped operations need a different key: creating and listing sub-accounts, allocating and releasing dedicated IPs, creating IP pools, and account-level stats and billing. A privileged credential, keep it in provisioning or admin tooling, never in the runtime send path and never in a client bundle.
The relay at smtp.sendpost.io does not accept an API key by convention. It uses SMTP AUTH over STARTTLS with a username and password issued in the dashboard. The docs say only to get those from your account and use placeholders throughout; they never state whether the username is a fixed literal, the sub-account key, or a generated pair. Read it from the dashboard rather than inferring another vendor’s pattern.
On the custom-SMTP path, where SendPost relays outbound through your own Postfix or MTA, the event reporting agent uses an Event Ingestion API Key that the docs explicitly describe as separate from the SendPost API key. Rotating one does not rotate the other, and a broken agent credential produces missing events rather than failed sends, easy to miss for weeks.
Three separate secrets, three lifecycles, and the same unhelpful 401 for any mismatch. Name them unambiguously in your secret store, and when debugging an authorisation failure check the path segment first: a request to /account/ippool/ carrying a sub-account key fails no matter how valid that key is.
SendPost publishes no numeric rate limits: no rate-limit page, no header contract, no plan table, because pricing itself is quote-based. The table states what is documented and what is not; nothing is borrowed from comparable vendors to fill the gaps.
| Limit | Documented value | Notes |
|---|---|---|
| Emails per hour | Not published | Set per contract. Ask during the demo, in writing. |
| Recipients per message | Not published | No recipient cap appears in the API reference. |
| Concurrent SMTP connections | Not published | No connection ceiling documented for smtp.sendpost.io. |
| API requests per minute | Not published | The feature page asserts rate limiting exists, without values. |
| Message size | Not published for the native API | 30 MB is the ceiling on the SendGrid-compatible endpoint only, returned as 413. |
| Relay retry policy | 5 attempts, linear backoff | Custom-SMTP path: 1h, 2h, 3h, 4h, 5h, then a CSDropped event. |
| Compatibility event latency | 1-5 seconds | SendGrid-compatible surface; duplicates cut on sg_event_id. |
The workaround is client-side throttling with server-side observation. With no published ceiling, treat 429 and 5xx as expected states: exponential backoff with jitter, concurrency capped at a value you chose rather than one you discovered, and a queue rather than a fan-out. If you route through a third-party sending provider, the TPSP model, where SendPost relays via your own SendGrid, Amazon SES, Mailgun, Postmark or SparkPost account, the binding limit is the upstream plan. Caps are contractual: if throughput matters, the number belongs in the order form.
Six official SDKs live in the github.com/sendpost organisation. Five were refreshed on the same day, December 26, 2025-a coordinated regeneration from the OpenAPI spec, not six release cycles. PHP followed three days later.
| Language | Package | Install | Repo |
|---|---|---|---|
| JavaScript | sendpost-js-sdk | npm install sendpost-js-sdk | GitHub |
| Python | sendpost_python_sdk | pip install sendpost_python_sdk | GitHub |
| Go | sendpost-go-sdk | go get github.com/sendpost/sendpost-go-sdk | GitHub |
| Ruby | sendpost-ruby-sdk | gem install sendpost-ruby-sdk | GitHub |
| Java | sendpost-java-sdk | Maven or Gradle, coordinates in the README | GitHub |
| PHP | sendpost/sendpost-php-sdk | composer require sendpost/sendpost-php-sdk | GitHub |
The marketing feature page advertises SDKs in over 14 languages. Only 6 repositories are verifiable. If your stack is C#, Rust, Elixir or Kotlin, assume you are writing an HTTP client, a small job, but one to scope rather than discover.
There are none worth naming, no third-party SendPost client library surfaced in package registries or public code search. The organisation ships official reference implementations instead: framework examples for Django, NestJS, Laravel, Rails and Spring Boot, and serverless examples for AWS Lambda, Vercel, Netlify, Cloudflare Workers and Supabase Edge Functions.
The 15 endpoints that matter in practice. Full schemas are in the official API reference; every path below is relative to https://api.sendpost.io/api/v1.
| Resource | Methods | Description |
|---|---|---|
| Email /subaccount/email/ | POST | Send with HTML, text or AMP body, custom fields, attachments, groups, headers and IP pool. |
| Email template /subaccount/email/template/ | POST | Send using a stored template instead of inline content. |
| Domain /subaccount/domain/ | POST, GET | Create a sending domain (returns DKIM, return-path, tracking and DMARC records) or list them. |
| Domain /subaccount/domain/{id}/ | GET, DELETE | Retrieve one domain with its verification state, or delete it. |
| Stats /subaccount/stats/ | GET | List raw sub-account sending statistics. |
| Stats aggregate /subaccount/stats/aggregate/ | GET | Aggregate sub-account statistics over a period. |
| Stats by group /subaccount/stats/group/aggregate/ | GET | Aggregate statistics broken down by message group. |
| Suppression /subaccount/suppression/ | GET, POST, DELETE | List, add to, or remove from the suppression list. |
| Message /subaccount/message/{id}/ | GET | Retrieve a message with its full delivery event history. |
| Webhook /subaccount/webhook/ | GET, POST | List or create webhook endpoints. |
| Webhook /subaccount/webhook/{id}/ | GET, PUT, DELETE | Retrieve, update or delete a webhook. |
| IP /account/ip/ | GET, POST | List or allocate a dedicated sending IP. Account-scoped key required. |
| IP /account/ip/{id}/ | GET, PUT, DELETE | Retrieve, update or release a dedicated IP. |
| IP pool /account/ippool/ | GET, POST | List or create IP pools for routing and traffic segmentation. |
| Sub-account /account/subaccount/ | GET, POST | List or create sub-accounts, the multi-tenant primitive for ESPs. |
Notice what is not there: no contact or list resource, no campaign object, no automation trigger, that is the sibling product SendX’s territory. SendPost’s object model is transactional: messages, domains, IPs, pools, tenants. Teams wanting that shape with a self-serve front door usually compare it against Resend, Postmark and MailerSend.
Because authentication is a plain header, the official JavaScript SDK is optional, a dependency-free client is a few lines, which is often the right call in a serverless function.
const res = await fetch('https://api.sendpost.io/api/v1/subaccount/email/', {
method: 'POST',
headers: {
'X-SubAccount-ApiKey': process.env.SENDPOST_SUBACCOUNT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: { email: 'richard@piedpiper.com', name: 'Richard' },
to: [{ email: 'gavin@hooli.com', name: 'Gavin' }],
subject: 'Hello World',
htmlBody: '<strong>it works!</strong>',
textBody: 'it works!',
trackOpens: true,
trackClicks: true,
}),
});
console.log(res.status, await res.json());A generated OpenAPI client, so header parameters are passed per call rather than configured once. Note the import name, sendpost_python_sdk-underscores, while the repository uses hyphens.
import sendpost_python_sdk
from sendpost_python_sdk.apis.tags import email_api
with sendpost_python_sdk.ApiClient() as api_client:
api_instance = email_api.EmailApi(api_client)
email = {
"from": {"email": "richard@piedpiper.com"},
"to": [{"email": "gavin@hooli.com"}],
"subject": "Hello World",
"htmlBody": "<strong>it works!</strong>",
"ippool": "PiedPiper",
}
api_response = api_instance.send_email(
header_params={'X-SubAccount-ApiKey': 'your_api_key'},
body=email
)
print(api_response)The Custom SMTP setup guide is the most misread page in SendPost’s documentation. It asks you to supply a running SMTP server. Postfix or any standards-compliant MTA, with its hostname or IP and port. Those are your credentials: SendPost relays outbound through your mail server and collects events via an installed agent. SendPost’s own relay is documented separately in the API introduction: smtp.sendpost.io, ports 25, 587 and 2525 for TLS, 465 for SSL. Credentials for a mailer plugin or a relayhost line come from there, not this page.
The older email-API feature page still promises a free forever plan of up to 25,000 emails a month with no credit card. The current product FAQ contradicts it outright: no free plan, no trial, and a demo plus an upfront financial commitment required. Self-serve signup went away with the repositioning toward ESPs. Budget for a sales conversation, and do not scope a project around the 25,000-email figure, it is stale copy nobody retired.
On the custom-SMTP path the documented retry policy is 5 attempts with linear backoff at 1h, 2h, 3h, 4h and 5h before SendPost emits a CSDropped event. A downstream MTA outage gives no terminal signal for up to 15 hours, and the failure surfaces as CSDropped rather than a bounce. Worse, deferred events are accepted by the ingestion API but not stored, so deferrals are invisible and you cannot watch a backlog build. Alert on CSDropped explicitly.
The SendGrid-compatible endpoint is a migration shim, not a clone. A SendGrid template_id returns 400 Bad Request-the docs say SendGrid templates are not supported and to include content directly or use SendPost native templates, so template-driven integrations need rework before cutover. Oversized requests return 413 with an instruction to stay below 30 MB; that ceiling belongs to the compatibility surface, not the native API. Event latency here is 1-5 seconds, with duplicates deduplicated on sg_event_id.
SendPost publishes no release-notes page, no changelog and no status page. The events below are verifiable observations, repository push dates and the state of the public product pages, not vendor announcements. Treat them as low-authority and confirm anything load-bearing with your account contact.
The closest thing to a canonical record of change is the OpenAPI specification. Diffing it on a schedule is a reasonable substitute for release notes.
The base URL is https://api.sendpost.io/api/v1. Authentication is a raw API key in a custom header, no OAuth, no bearer token. Sending and sub-account calls use X-SubAccount-ApiKey; account-level calls use X-Account-ApiKey. Everything is JSON, and the machine-readable contract is the OpenAPI specification.
Scope, and the path prefix tells you which a call needs. X-SubAccount-ApiKey covers the sending plane under /subaccount/: email, templates, domains, stats, suppressions, webhooks. X-Account-ApiKey covers the control plane under /account/: sub-accounts, dedicated IPs, IP pools, billing. The wrong key returns a bare 401 with no indication of the expected scope, so check the path segment first. A third credential, the Event Ingestion API Key, is used only by the custom-SMTP event agent.
Six: JavaScript, Python, Go, Ruby, Java and PHP, all in the github.com/sendpost organisation. Five were refreshed on December 26, 2025 and PHP on December 29, 2025. The marketing page claims over 14 languages, but only these six are verifiable, for anything else, write a thin HTTP client from the OpenAPI spec. The org also publishes framework and serverless reference examples.
Neither is published. No documented requests-per-minute ceiling, emails-per-hour cap, recipient limit, connection limit or native message size limit. Two adjacent numbers get misquoted: the 30 MB payload ceiling applies to the SendGrid-compatible endpoint only, and the five-attempt retry schedule applies to the custom-SMTP relay path. Because pricing is quote-based, caps are per contract, get yours in writing during the demo.
SendPost delivers signed HTTP callbacks for delivery, open, click, bounce, complaint and unsubscribe events. The exact header name and hashing scheme are in the webhook object reference-read it there rather than assuming another vendor’s convention. Register endpoints with POST /subaccount/webhook/ using a sub-account key, and verify before acting on a payload.
No. As of August 2026 there is no official SendPost MCP server, no community wrapper and no commercial one. The GitHub organisation’s 43 repositories contain no MCP project, the docs index publishes no MCP page, and no entry appears in public MCP directories. An “MCP Registry” label in site navigation does not resolve to a SendPost-published server. SendPost does ship an llms.txt docs index, which helps LLMs read the documentation but is not MCP. To give an agent capability today, generate a server from the OpenAPI spec, restrict the tool list, and scope it to a sub-account key.
This review follows our email infrastructure testing methodology. We disclose affiliate relationships in our editorial independence policy.