saransh@web

Your API Should Be Boring, And That’s a Good Thing

Send request, get JSON, job done — until the project grows. On predictable resources, honest status codes, locks installed before launch, and why the best APIs have no personality at all.

7 June 2026 · 4 min read · updated 1 Sept 2026 · #api design #payload #next.js #security

api-image
~/notes/your-api-should-be-boring/cover

APIs are one of those things that can look beautifully simple from the outside.

Send request. Get JSON. Job done.

Then the project grows.

Now there are twelve endpoints, three slightly different ways to return an error, a mysterious /getAllUsers, permissions that exist mostly on vibes, and one response shape nobody wants to change because something will probably explode.

Been there.

The good news is that designing a solid API isn’t really about being clever. In fact, the best APIs are usually kind of boring.

Predictable. Consistent. Secure. Easy to guess.

And boring infrastructure is underrated.

Start with the resource, not the action#

When I’m working with Next.js, React and Payload, I find it useful to think about the actual thing the API represents before thinking about endpoints.

Say we’re dealing with blog posts.

Instead of inventing routes like:

/api/getPosts
/api/createPost
/api/deletePost

I’d rather let HTTP do the talking:

GET /api/posts
GET /api/posts/:id
POST /api/posts
PATCH /api/posts/:id
DELETE /api/posts/:id

Posts are the resource. The HTTP method describes what we’re doing with them.

Nothing revolutionary here.

That’s exactly the point.

A developer looking at those endpoints can understand the basic API without opening a 47-page Notion document.

Big win.

Consistency beats cleverness#

If one endpoint returns:

{ "data": { … } }

another returns:

{ "result": { … } }

and another just throws some mystery object into the void, your frontend is going to have a fun afternoon.

Pick conventions and stick with them.

That applies to naming, pagination, filtering, dates, errors and response structures.

For example:

?page=2&limit=20

is boring.

Perfect.

Your React components shouldn’t need detective skills to figure out what an API is trying to say.

HTTP status codes already exist. Use them.#

You don’t need to reinvent errors either.

200 means we’re good.
201 means something was created.
400 means the request isn’t valid.
401 means authentication is required.
403 means the user is authenticated but isn’t allowed to do that.
404 means the thing isn’t there.
429 means somebody needs to chill with the requests.
500 means something went wrong on the server.

The important part is consistency.

I also like returning an error body that’s actually useful:

{ "error": { "code": "POST_NOT_FOUND",
"message": "The requested post could not be found." } }

A frontend can work with that.

Something went wrong :) is considerably less helpful.

Security is not the final checklist item#

This is the bit I really don’t like treating as an afterthought.

An API is a door into your application.

Maybe don’t install the lock three days before launch.

Authentication answers:
Who are you?

Authorization answers:
Are you allowed to do this?

You need both.

A logged-in Payload user shouldn’t automatically have permission to modify every collection just because they managed to authenticate.

Define access rules close to your data. Validate input on the server. Never trust values simply because they came from your own React frontend.

Clients can be modified.
Requests can be forged.
IDs can be changed.

Your API should assume that eventually somebody will send it something weird.

Also: HTTPS everywhere, sensible CORS rules, secure cookies or properly handled tokens, rate limiting where appropriate, and no secrets casually shipped to the browser.

And please don’t put your secret API key in NEXT_PUBLIC_*.

The word public is doing a lot of work there.

Validate everything#

TypeScript is great.

TypeScript also disappears at runtime.

If an endpoint expects an email address, validate that it’s an email address.

If page should be a positive integer, check it.

If a field can only contain a specific set of values, enforce that on the server.

Payload helps here because your collection schemas already provide structure and validation, but custom endpoints and external integrations still need the same level of care.

Never assume:

“The frontend won’t send that.”

The frontend absolutely can send that.

Don’t send the entire universe#

Another easy API win is returning only what the client needs.

If a blog card needs a title, slug, excerpt and image, it probably doesn’t need the complete document with every relationship populated five levels deep.

More data means more database work, larger responses and more JavaScript doing things it never needed to do.

Filtering, pagination and field selection aren’t fancy API features.

They’re how you stop a perfectly innocent GET request from becoming a small infrastructure event.

Version when change becomes dangerous#

APIs evolve.

Fields change. Requirements change. That “temporary” integration from two years ago is somehow now business-critical.

If you control both your Next.js frontend and Payload backend, you might not need formal versioning immediately.

But once external consumers depend on your API, breaking changes become a different problem.

That’s when something like:

/api/v1/posts

starts making sense.

Version deliberately, not automatically.

The goal isn’t to collect /v1, /v2, /v3 like Pokémon. It’s to give consumers stability when the contract needs to change.

The boring API wins#

Good API design isn’t about having the most elaborate architecture diagram.

It’s about making the next request unsurprising.

A developer should be able to look at one endpoint and make a decent guess about how another one behaves.

Keep resources understandable.
Use HTTP properly.
Return consistent responses.
Validate input.
Lock down access.
Handle errors like you actually expect someone to encounter them.
Log what matters.
Document the weird bits.

And don’t optimize for complexity just because complexity looks impressive.

Your API doesn’t need personality.

Your website can have the personality.

Let the API be boring.

Boring is predictable.

Predictable is maintainable.

And maintainable means future-you has one less reason to stare at the screen at 2:14 AM wondering who designed this thing.

Plot twist: it was you.