How to Add a Public API to an AI-Built App

A practical, step-by-step guide to exposing a public REST API on your AI-built app: pick the right endpoints, generate API keys, add rate limiting, version your paths, and write docs people can actually use.

Steve Jefferson
Steve Jefferson
Developer Advocate
18 August 20261 min read

If you built your app with an AI tool and now need to let other developers or your own frontend talk to it programmatically, you need a public API: a small set of documented HTTP endpoints, an API key system for authentication, rate limits to keep it stable, and a version in the URL so you can change things later without breaking anyone. None of this requires a backend engineering background. It's a checklist you can work through in an afternoon.

This guide walks through the five pieces in order: picking endpoints worth exposing, generating and checking API keys, adding rate limiting, versioning the path, and writing docs someone can actually use. It assumes you've already got a working app, whether you followed a general guide to building an app with AI or pieced your stack together on your own.

Start with two or three endpoints, not ten

The instinct when opening up a rest api for ai app is to expose everything the app can do. Resist it. Every endpoint you publish is a contract you have to support forever, even after you rebuild the internal logic behind it.

Pick the two or three actions that outside users actually need. If you built a task management app, that's probably "list tasks" and "create a task," not fifteen endpoints covering every internal state transition.

A clean endpoint has:

  • A predictable URL built around a noun (/v1/tasks, not /v1/getAllTasksForUser)

  • One clear HTTP verb per action: GET to read, POST to create, PATCH to update, DELETE to remove

  • A consistent JSON response shape, even for errors

Here's what a well-formed response looks like for a single resource:

GET /v1/tasks/482
Authorization: Bearer sk_live_51a9c...

{
  "id": 482,
  "title": "Ship API docs",
  "status": "open",
  "created_at": "2026-08-15T14:02:00Z"
}

And an error response should follow the same shape every time, not a raw stack trace:

{
  "error": {
    "code": "not_found",
    "message": "No task with id 482"
  }
}

If every AI coding session generates errors differently, that's the first thing to standardize before you open the API to anyone outside your own app.

Generate API keys instead of reusing user passwords

A public API needs its own authentication, separate from however people log into your app's web interface. The standard pattern for api keys for your app is a long random string tied to one account, sent on every request.

Generate keys server-side. Never let a client pick its own key. A simple version looks like this:

  1. Generate 32 random bytes and encode them as a hex or base62 string.

  2. Prefix it so keys are recognizable in logs, for example sk_live_ for production and sk_test_ for a sandbox.

  3. Store a hash of the key in your database, not the plain string. Treat it like a password.

  4. Show the full key to the user exactly once, at creation time, and never display it again.

When a request comes in, you hash the presented key and look up the hash. That's it. No sessions, no cookies, no CSRF handling to think about for API traffic.

The key gets sent as a bearer token in the Authorization header:

Authorization: Bearer sk_live_51a9c3f7e8b2d4a6910f2c5e7b1a3d90

Reject any request without a valid key with a 401 and a clear message, not a silent failure or a 500 error. Someone integrating against your API for the first time will thank you for that.

Give users a way to revoke and regenerate keys from a settings page. Keys leak: they end up in screenshots, committed to public repos, or pasted into a chat tool. Revocation needs to be instant and self-serve, not a support ticket.

Add rate limiting before you need it

Rate limiting isn't optional once an endpoint is public. Without it, one misbehaving script, a retry loop with no backoff, or a scraper can take your app down for every other user at the same time.

You don't need anything elaborate to start. A basic approach to api rate limiting:

  • Count requests per API key in a fixed window, for example 60 requests per minute.

  • Store the count somewhere fast, like Redis or an in-memory store if you're running a single instance.

  • Reject requests over the limit with a 429 status and a Retry-After header.

  • Return the remaining quota in response headers so well-behaved clients can self-throttle.

A rejected request should look like this:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Retry after 30 seconds."
  }
}

Set different limits for different tiers if it makes sense: a lower ceiling for free accounts, a higher one for paid ones. Most AI app builders and backend-as-a-service platforms have a rate limiting primitive or middleware built in. If yours doesn't, a simple counter tied to the API key with an expiring window covers the majority of real-world abuse cases without much code.

Put a version in the URL from day one

Version your API path before you ship the first endpoint, not after the first breaking change. The convention is a version segment at the start of the path: /v1/tasks, /v1/users, and so on.

This matters because your app will change. You'll rename a field, restructure a response, or drop something nobody uses. Without a version in the path, every change is a breaking change for anyone already integrated. With /v1/ in place, you can ship /v2/ later and run both side by side while people migrate on their own schedule.

Two rules keep this simple:

  1. Never change the shape of a response inside an existing version. Add new optional fields if you need to, but don't rename or remove existing ones.

  2. When you do need a breaking change, bump the version and keep the old one running for a defined deprecation period, not an indefinite one.

Skipping versioning is the single most common mistake in a first public API, and it's the hardest one to retrofit once outside code depends on your exact response shape.

Write documentation before anyone asks for it

Minimal docs beat no docs, and they don't need to be a full developer portal. A single page covering the essentials is enough to launch with:

  • Base URL and version, for example https://api.example.com/v1

  • How to get an API key and where to send it

  • Each endpoint: method, path, required parameters, and one full example request and response

  • What the error format looks like

  • The current rate limit

Write the example requests as copy-pasteable curl commands. Most developers testing a new API will paste your example straight into a terminal before reading a word of prose. If it doesn't work as pasted, that's the first thing they'll notice.

curl https://api.example.com/v1/tasks \
  -H "Authorization: Bearer sk_live_your_key_here"

Keep the docs in the same repo or CMS as the API itself so they don't drift out of sync when you change something. A docs page that's wrong is worse than no docs page, because it costs someone real debugging time before they realize the problem is your documentation, not their code.

Putting it together

A public API for an AI-built app doesn't need a dedicated backend team behind it. It needs a handful of well-shaped endpoints, keys that are generated and stored safely, a rate limit that protects the app from accidents, a version segment that gives you room to change your mind later, and a docs page honest enough to save someone a support email.

Start with the smallest useful surface area. You can always add endpoints. Removing ones people already depend on is the hard part, and versioning is what makes that possible without breaking anyone's integration.

If you haven't yet set up user accounts or role-based access for your app, exposing endpoints safely usually depends on that groundwork being in place first, since API keys are typically tied to an authenticated account. The same applies if you're planning to trigger outside systems: adding webhooks is a closely related pattern that works alongside a public API rather than replacing it. And once the API is live, deploying the app and keeping an eye on running costs both become more important, since a public API tends to increase traffic to your backend.

Frequently asked questions

Do I need OAuth instead of API keys for a public API?

Not for most first-party integrations. API keys are simpler to implement and simpler for developers to use for server-to-server calls. OAuth makes sense when third-party apps need to act on behalf of your users without ever seeing their credentials, which is a different problem than exposing your own endpoints.

How many requests per minute should I allow?

There's no universal number. Start conservative, something like 60 requests per minute per key, watch your logs for a few weeks, and adjust based on what legitimate usage actually looks like versus what triggers abuse.

Should my public API and my app's internal API be the same thing?

No. Keep them separate, even if they share a database. Your internal API can change freely as you iterate. Your public API needs the stability guarantees that come with versioning and a documented contract.

What happens if I forget to add a version to my API path?

You can still add one later by introducing /v1/ as new routes and treating the old unversioned paths as a permanent, frozen legacy version. It's more painful than versioning from the start, but it's recoverable.

Do I need a full API gateway to do this?

No. A single middleware function that checks the API key, applies a rate limit, and routes to versioned handlers covers the requirements for a first public API. A gateway becomes useful later, once you have multiple services or need more granular traffic controls.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.