Blog

Every API needs a natural language endpoint

Jan 25, 2025

The barrier-to-entry to using developer APIs is significantly high. First you have to be a developer and understand the basics of HTTP requests and responses. Next, you need to spend time reading the API documentation, determining what type of API it is, and then learning how to actually interact with the data the API provides.

Let’s take a step back. Ask yourself: what is the most common purpose behind using developer APIs at all?

Usually it’s just to retrieve and/or update data from a third party system.

So let’s imagine you are building an ecommerce product that fulfills orders from different vendors. You need to use a vendor’s developer API to look up a product by name and add it to your existing order. Usually, you’d look up the REST endpoints needed and make multiple requests to the API.

What if you could do this instead?

const res = await fetch(`https://imaginaryapi.mastra.com/api/chat`, {
  method: 'POST',
  body: {
    message: `Find product ${product_title} and add it to order ${order_id}`,
  }
  headers: {
    Authorization: `Bearer ${process.env.MY_API_KEY}`,
  },
});

In other words, what if every API had a /chat endpoint where you could specify exactly what you need? In this case, it’s to ‘find product X and add it to order Y.’

What about reliability and latency?

Now you might be thinking: LLMs are not 100% reliable, so why would I want a chat endpoint if I can’t rely on it to work 100% of the time?

And what about latency? This request would be slower than simply calling the API directly!

Both points are true and, at a certain scale, you can’t rely on chat endpoints. But most applications aren’t built for massive levels of scale. They certainly don’t need 4 nines, i.e. 99.99%, of reliability.

Even for the applications that do require guaranteed amounts of reliability, almost all of them start out as prototypes (or at least they should.) And there is no better way to rapidly prototype and iterate than to use natural language on a single API endpoint.

Once you scale and need such levels of reliability, you will likely either throw away the initial prototype and start over or use Cursor, pass in the API docs, and have it update them all. (Since you are already using natural language in your code, Cursor will do a reasonably good job of using the right endpoints and data structures.)

What about API versioning?

The chat endpoint for any individual API will need to be versioned just like any other API — the only difference is that it could change more frequently.

If the API developer changes the underlying model or system prompt, any applications built on top of that API could be impacted significantly, thus impacting reliability. Because of this, my recommendation would be for every API developer to have rolling versions, i.e. just put in the date of when you started (or last tested) your application. The API should automatically be able to use the correct underlying model and system prompt from that point in time.

Applying it to our example, we get:

const res = await fetch(`https://imaginaryapi.mastra.com/api/chat`, {
  method: 'POST',
  body: {
    message: `Find product ${product_title} and add it to order ${order_id}`,
  }
  headers: {
    Authorization: `Bearer ${process.env.MY_API_KEY}`,
    'Api-Version': '2025-01-16',
  },
});

Now if you are rebuilding parts of your application, you can always update the Api-Version to the current date and retest. Hopefully you get good, if not better, results.

The future is standardized chat API protocols

Not every API is going to magically develop chat endpoints over the next 6 months but, over time, I believe many will. If we develop a standardized chat API protocol, it’ll be easier for more APIs to adopt chat endpoints and, therefore, easier for developers to integrate APIs into their prototypes and applications.

Share

Stay up to date