Home Arrow Blog Arrow AI SDK
...
Arrow
API Protocols in 2026: 9 Types, Real Trade-offs, and When Each Wins

AI SDK

Updated on Oct 14, 2026

API Protocols in 2026: 9 Types, Real Trade-offs, and When Each Wins

api protocols for chat and AI

In 2015, you would choose between REST and SOAP. Today, API protocol decisions are much broader – it’s not about picking one, but about what protocol fits the job. 

If you standardize on one protocol for everything, you’ll face issues like slow mobile clients, non-working real-time features, or other overhead. Moreover, there are protocols for LLMs that didn’t even exist three years ago. So, you need to know where and what to use.

In this article, we’ll cover nine protocols, with real code for each, real trade-off numbers, and a decision framework to make it easier for you.

In this article 

What Is an “API Protocol”

An API protocol defines how two systems communicate – how data is sent, received, and structured.

It covers things like:

  • Transport: HTTP, WebSocket, QUIC
  • Format: JSON, XML, protobuf
  • Interaction: request/response, streaming, pub/sub
  • Contract: OpenAPI, GraphQL, .proto

This is different from the API type, which describes who can access it – public, private, or partner. For example, a private API can use REST, GraphQL, or gRPC. API type and protocol are separate decisions.

HTTP/1.1 often opens a new connection per request. HTTP/2 can handle multiple streams over one connection, while WebSocket keeps a persistent connection for real-time communication.

You might not notice the difference in a demo, but under real production load it may affect latency, resource usage, and how many users your system can handle.

The 9 Protocols

Now, let’s consider the protocols you may use. There are nine – let’s find out which communication mechanism fits which problem.

REST (Representational State Transfer)

REST remains the right default for public external APIs. HTTP verbs map to operations (GET/POST/PUT/PATCH/DELETE), resources map to URLs, and the entire HTTP ecosystem – caching headers, CDN support, browser DevTools, OpenAPI tooling – works without any additional setup.

The limitation is the N+1 problem. A mobile screen needing a profile, messages, unread count, and presence status requires four REST requests. At 200ms each, that’s 800ms before rendering. Teams often respond with batch endpoints – or migrate to GraphQL.

// Fetch a channel with its 50 most recent messages
GET /api/channels/42?include=messages&limit=50
Authorization: Bearer <token>

// Response — 2 resources in 1 request only if API was designed for it
// Otherwise: GET /channels/42 then GET /channels/42/messages?limit=50

GraphQL

GraphQL, open-sourced by Facebook in 2015, solves the client-side N+1 problem by letting clients request exactly what they need in one round-trip. Apollo Federation and Hive help teams manage schemas across multiple backend services.

The trade-off: N+1 can move to the server. DataLoader prevents inefficient per-user queries, but requires deliberate implementation. Schema design also adds overhead. For simple CRUD or third-party APIs, REST is often simpler. GraphQL shines when clients iterate quickly and need control over data shape without backend changes.

// GraphQL query — client declares exactly what it needs
query ChannelView($id: ID!) {
  channel(id: $id) {
    name
    members { id displayName avatarUrl }
    messages(last: 50) { id text createdAt author { id displayName } }
    unreadCount
  }
}

gRPC

gRPC (Google, 2016) runs over HTTP/2 with protobuf encoding. HTTP/2 transport provides multiplexed streams and binary framing. Protobuf payloads are 30-50% smaller than equivalent JSON and parse faster. The .proto file serves as the source of truth for the API contract across all languages – generate stubs for Go, Java, Node, Python, .NET, and Swift from the same file. 

First-class bidirectional streaming is the capability that separates gRPC from REST. A gRPC service can stream requests, stream responses, or both simultaneously – the right shape for real-time analytics ingestion, AI inference pipelines, or any backend-to-backend flow with continuous data. gRPC-Web and the Connect protocol (from Buf) bring this to browser clients, though with some constraints. For service mesh communication in Go or Java systems, gRPC is now the default at companies like Netflix, Square, and Cloudflare.

// .proto contract — generates client/server stubs for any language
service ChatService {
  rpc SendMessage(MessageRequest) returns (MessageAck);
  rpc StreamMessages(ChannelId) returns (stream Message);
}

tRPC 

tRPC is the TypeScript-monorepo answer to “why do I need a schema file and code generation for an internal API?” Define server procedures in TypeScript, call them from the client with full type inference, no codegen step required. The types flow from server function to client at compile time. Used heavily in the Next.js + Node.js ecosystem. 

The constraint is right there in the name: TypeScript-only. If your backend is Go or your mobile client is Swift, tRPC isn’t available. Teams hit this when they scale to a second platform or hire a backend team that prefers a different language. For a fast-moving TypeScript monorepo where backend and frontend are owned by the same team and external clients don’t exist, it’s the best developer experience of any API protocol currently available.

// Server — define typed procedures
export const chatRouter = t.router({
  send: t.procedure
    .input(z.object({ channelId: z.string(), text: z.string() }))
    .mutation(({ input }) => messages.save(input)),
});

// Client — full type inference, zero schema, zero codegen
await trpc.chat.send.mutate({ channelId: '42', text: 'hi' });

WebSocket

WebSocket is a persistent, bidirectional TCP connection that starts by doing an HTTP upgrade and then uses frames. Either side can push messages whenever it wants without making any request.

WebSocket fits perfectly for applications like chatting, presence, gaming, live dashboards, and collaboration where latency needs to be low, and frequency needs to be high. The downside is increased complexity in operations involving things like reconnection, routing through multiple nodes, offline queueing, and message retransmission.

// Client
const ws = new WebSocket('wss://api.example.com/chat');
ws.onmessage = e => render(JSON.parse(e.data));
ws.send(JSON.stringify({ type: 'message', channel: '42', text: 'hi' }));

// Server (Node.js, ws library)
wss.on('connection', socket => {
  socket.on('message', msg => fanout(socket, JSON.parse(msg)));
});

SSE (Server-Sent Events) 

SSE is a one-way HTTP stream from server to client – the EventSource API has been in browsers since 2009 and requires zero additional libraries. The server sends newline-delimited data: chunks; the client reads them as they arrive. Per-event overhead is essentially zero beyond HTTP headers already paid at connection setup. 

SSE’s 2024-2026 growth driver is LLMs. Both OpenAI and Anthropic stream token-by-token responses via SSE. Any product that pipes an LLM response to a browser is already using SSE. If you’re building an AI assistant feature, passing the SSE stream through your backend to the client is simpler than converting it to WebSocket at the server boundary – same protocol shape on both ends, no format translation. The direction constraint (server to client only) is not a real limitation for streaming use cases; clients send prompts via HTTP POST and receive the stream back via SSE.

// Server
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
for await (const token of llm.stream(prompt)) {
  res.write(`data: ${JSON.stringify({ token })}\n\n`);
}

// Client
const es = new EventSource(`/api/stream?prompt=${encodeURIComponent(prompt)}`);
es.onmessage = e => appendToken(JSON.parse(e.data).token);

Webhooks

Webhooks are HTTP callbacks: a provider POSTs to your URL when an event occurs. They’re inherently async – the webhook returns 200 while your system processes the event independently.

Three operational requirements matter: signature verification to prevent forged events, idempotency because providers retry, and burst handling with a queue for high-volume events.

// Express receiver — with signature verification
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  try { event = stripe.webhooks.constructEvent(req.body, sig, process.env.WH_SECRET); }
  catch { return res.sendStatus(400); }
  queue.push(event);  // process async, respond fast
  res.sendStatus(200);
});

SOAP

SOAP (1998, XML-based, WSDL contracts, WS-Security for enterprise auth) has one honest use case in 2026: talking to systems that already speak it. Legacy banking, insurance, and government systems frequently expose SOAP endpoints that haven’t been replaced because replacing them is expensive and risky. If you integrate with one, generate a SOAP client from the WSDL and move on. There is no circumstance where you should design a new API as SOAP.

MCP (Model Context Protocol) 

MCP is Anthropic’s open standard for exposing tools and data sources to language models. It defines how an LLM client discovers what capabilities a server offers, calls those capabilities, and handles the response – replacing the ad-hoc “function calling” implementations that every LLM integration was previously building from scratch. OpenAI, Google, and a growing number of third-party tools have adopted the spec since its 2024 release. MCP is not a general-purpose messaging protocol – it bridges AI models and tool servers.

MCP’s value is standardization. Before MCP, if you wanted GPT-4 to search your database, Claude to do the same, and Gemini to do the same, you built three separate integrations with three different function-calling schemas. With MCP, you build one MCP server exposing the search_database tool, and any MCP-compatible model client can call it. The protocol handles discovery, invocation, and response handling in a consistent way across models.

// MCP server — Node.js (tools exposed to any MCP-compatible LLM)
server.setTool('search_messages', {
  description: 'Search message history by query',
  schema: z.object({ query: z.string(), channelId: z.string() }),
  handler: async ({ query, channelId }) =>
    db.messages.search({ query, channelId }),
});

Benchmarks: What Actually Differs in Production

The numbers below are directional, based on published benchmarks from Google, Cloudflare, and independent protocol research. Measure under your own load before capacity planning.

ProtocolLatency P50Payload (150-byte message)Server overhead / 1M connectionsStreaming
REST (JSON/HTTP)15-30ms~250 bytes on wireNew connection per requestNo
GraphQL (JSON/HTTP)20-50ms~250 bytesSame as RESTSubscriptions only
gRPC (protobuf/HTTP2)5-15ms~110 bytesMultiplexed streams✅ Native bidi
tRPC (JSON/HTTP)15-30ms~250 bytesSame as RESTSubscriptions via WS
WebSocket10-30ms per message~156 bytes (6-byte frame + payload)~2-4 GB RAM per 1M idle✅ Full-duplex
SSE10-30ms per event~200 bytes (HTTP chunk overhead)~1-2 GB RAM per 1M idle (simpler state)✅ Server→client
WebhooksSeconds (async)Variable (full event payload)Stateless per requestNo (callback)
SOAP20-80ms~400–800 bytes (XML verbose)New connection per requestVia WS-Eventing
MCP<5ms protocol overheadJSON per tool callDepends on transport (stdio/HTTP)Tool streams

The gRPC latency advantage is real and comes primarily from HTTP/2 multiplexing (no head-of-line blocking between requests) and protobuf’s compact encoding. A 30% payload reduction that also parses faster compounds at high request volume. For a backend service handling millions of inter-service calls per minute, this matters. For a frontend making 10 API calls on a screen load, it doesn’t.

The WebSocket server RAM figure – 2-4 GB per million idle connections – is why WebSocket backends need to think about horizontal scaling from day one. A single Node.js process at 10,000 concurrent users is fine. At 100,000 it’s tight. At 1mln you need a cluster with a pub/sub broker routing messages between nodes. That infrastructure exists and is well-understood; it just needs to be designed for rather than discovered in production.

Pick Protocol Per Surface

This table will help you decide what protocol you need. But don’t forget that picking one protocol for everything is usually the wrong call.

Public API for third-party developersREST + OpenAPI. Maximum tooling, universal client support, existing ecosystem knows how to consume it
Mobile client, complex screen data, N+1 problemGraphQL. One round-trip, client-defined shape, Federation for multi-team
Backend microservices, polyglot, high throughputgRPC. Protobuf contracts, HTTP/2 multiplexing, bidi streaming, generated stubs in any language
TypeScript monorepo, internal API, same team owns both sidestRPC. End-to-end type safety, zero codegen, fastest DX available
Chat, presence, typing indicators, live stateWebSocket. The only protocol designed for high-frequency bidirectional text at low latency
LLM streaming responses, server push notificationsSSE. Matches OpenAI and Anthropic API shape exactly; cheaper server-side than WebSocket for one-way
Event notifications from third-party systemsWebhooks. HTTP callbacks with signature verification and idempotency keys
Integrating with a legacy bank, insurer, or government systemSOAP. Only if required. Generate a client from the WSDL and don’t design anything new in it
Exposing your APIs as callable tools to AI agentsMCP. The emerging standard; build now, not as a retrofit in 12 months

Which Protocols Do Chat + AI SDKs Use?

If you’re planning to use a chat SDK when adding chat API features to your product, you may wonder whether it abstracts the right protocol mix, or forces you to use the wrong one. 

An SDK that uses only REST for everything is either polling (wasteful) or long-polling (wasteful and slow). An SDK that uses only WebSocket for everything pays the stateful connection overhead even for operations that don’t need it.

A well-designed chat SDK like Ethora uses the right protocol where it’s needed:

  • REST for the control plane (create channel, fetch history, upload file, manage users) 
  • WebSocket for real-time chat (deliver messages, presence, typing) and presence via the self-hosted chat server
  • SSE for LLM streaming responses
  • Webhooks for third-party integration events

MCP is the newest addition to this list. Our MCP server enables LLM clients to search message history, send messages, list channels, and query user presence as AI tool calls – without any custom integration work from the developer. This turns a chat API into an AI-accessible knowledge base and action surface with one server implementation. The self-hosted LLM AI agent configuration lets you swap between OpenAI, Anthropic, or a local model by changing an endpoint value.

The gap worth naming: there is no GraphQL API surface. The control plane is REST. For teams that have standardized on GraphQL for their mobile clients and want to query Ethora’s SDK via the same GraphQL layer they use for everything else, this requires building a GraphQL wrapper over the REST endpoints – or picking another provider, which has partial GraphQL support.

Anyway, Ethora is a great choice for your web, Android, and iOS applications, especially if you build for regulated industries like finance or healthcare, and you need to comply with regulations. WebSocket, REST, and SSE stack as the web SDK ensure consistent protocol behavior across platforms, which matters for audit trail completeness. The self-hosted deployment means all five protocol surfaces (REST, WebSocket, SSE, Webhooks, MCP) stay within your infrastructure boundary, which is the key requirement for a HIPAA-compliant messaging API where every data flow must be within a BAA-covered boundary.

Share with your community

Try Out Ethora in Action

Experience Ethora's messaging with a dedicated demo from our CEO or start building your App right now!

Free Sign Up