Guides / Prompting and shipping

How to Build a REST API: Design, Security and Deployment

Build a REST API step by step: resources and routes, HTTP methods and status codes, validation, authentication, pagination, rate limits, docs and deployment.

Mythex Team · 2026-09-29 · 5 min read

To build a REST API, list the resources your app manages (users, orders, bookings), give each a URL such as /orders and /orders/{id}, and use HTTP methods for actions: GET to read, POST to create, PATCH to update, DELETE to remove. Return JSON with meaningful status codes, validate every input, require authentication and per-record permission checks on the server, and paginate lists. Then document the endpoints and deploy the API behind HTTPS.

This guide covers the design decisions, a worked set of routes, prompts for an AI app builder, and the mistakes that cause security holes. If APIs are new to you, start with what an API is.

When you need a REST API

  • Your web frontend needs to save and load data from a server
  • A mobile app, partner or automation tool needs access to your data
  • Other services send you events (webhooks)
  • You're splitting work between a frontend and a backend team

REST is the most common style, but not the only one. REST vs GraphQL explains when a single flexible query endpoint fits better.

Design first: resources and routes

Write down the nouns in your app and what people do with them. For a simple booking app:

MethodRouteWhat it doesSuccess code
GET/api/bookingsList the caller's bookings (paginated)200
POST/api/bookingsCreate a booking201
GET/api/bookings/{id}Get one booking200
PATCH/api/bookings/{id}Change some fields200
DELETE/api/bookings/{id}Cancel a booking204
GET/api/healthHealth check for monitoring200

These map onto create, read, update and delete; see what CRUD is. Conventions worth following:

  • Plural nouns, no verbs in URLs: /bookings, not /getBookings.
  • Nest only one level when it clarifies ownership: /bookings/{id}/notes.
  • Actions that aren't CRUD can be sub-resources: POST /bookings/{id}/cancel is clearer than a magic PATCH.
  • Consistent naming for fields, such as created_at everywhere.

Status codes and errors

Use standard HTTP codes so clients know what happened without parsing text:

CodeMeaningUse when
200OKSuccessful read or update
201CreatedA POST created something
204No ContentSuccess with nothing to return
400Bad RequestInput failed validation
401UnauthorizedNot logged in or bad token
403ForbiddenLogged in but not allowed
404Not FoundDoesn't exist, or the caller mustn't know it exists
409ConflictDuplicate, or the slot is already booked
429Too Many RequestsRate limit hit
500Server ErrorSomething broke on your side

Return errors in one consistent JSON shape, for example {"error": {"code": "slot_taken", "message": "That time is no longer available."}}, and never include stack traces or database errors in responses.

Options and trade-offs

DecisionSimple choiceAlternative
Where the API livesAPI routes in your web frameworkA separate API service, useful for several clients or a different language
AuthenticationSession cookies for your own web appTokens (bearer tokens or API keys) for mobile apps and third parties
Pagination?page=2&limit=20Cursor-based (?after=...), steadier for large, changing lists
VersioningNone until you have outside users/v1/ in the path once others depend on it
DocsA README listing routesAn OpenAPI spec, which tools can turn into interactive docs and client code

Step by step

  1. List resources and routes as above, including who may call each.
  2. Model the data in your database with the fields and relationships you need.
  3. Build read routes first, then create, update and delete.
  4. Validate input on every write with a schema library: required fields, types, lengths, allowed values. Reject unknown fields.
  5. Add authentication, then authorisation per record: loading /bookings/42 must check that booking 42 belongs to the caller, not just that someone is logged in.
  6. Paginate every list and cap the page size.
  7. Rate-limit login and expensive routes. See rate limiting.
  8. Configure CORS only if browsers on other domains must call the API, and list those origins explicitly. How to fix CORS errors explains the errors you'll see.
  9. Write docs and tests for each route, including the failure cases.
  10. Deploy with secrets in environment variables, HTTPS, logs and a health check.

Prompts to give your AI builder

Scaffold:

Create a REST API for bookings with these routes: GET /api/health, GET /api/bookings (paginated, max 50 per page), POST /api/bookings, GET /api/bookings/:id, PATCH /api/bookings/:id, DELETE /api/bookings/:id. Store data in our database. Validate request bodies with a schema library and reject unknown fields. Return JSON errors as {"error": {"code", "message"}} with correct status codes (400, 401, 403, 404, 409). Keep secrets in environment variables.

Security:

Require login on every bookings route. On every read, update and delete, check on the server that the booking belongs to the current user; return 404 if it doesn't. Never accept user IDs or roles from the request body. Rate-limit POST /api/bookings to 20 per minute per user. Log errors on the server without returning stack traces.

Docs:

Write an OpenAPI description of these routes, and a short README with example requests and responses for each.

Testing your API

Test from outside the frontend, because attackers will:

  • Each route works with valid input and returns the documented shape and code
  • Missing or invalid fields return 400 with a clear message
  • No token returns 401 on every protected route
  • User A requesting user B's record by ID gets 404 or 403
  • Lists are paginated; a huge limit is capped
  • Duplicate or conflicting creates return 409, not 500
  • Rate limits return 429
  • Error responses contain no stack traces, SQL or secrets
  • CORS allows only the origins you intend

Common mistakes

  • Checking login but not ownership. The most common API hole: any logged-in user can read any record by changing the ID.
  • Trusting the client. Prices, roles and user IDs from the request body can be edited.
  • Returning whole database rows. Password hashes and internal fields leak. Choose what each response includes.
  • Unbounded lists. One request for every record can slow the whole app.
  • 200 OK with an error message inside. Clients and monitoring can't tell it failed.
  • CORS set to allow everything on an API that uses cookies.
  • No health check or logs, so you find out about outages from users.

For a broader pre-launch pass, see the security checklist for AI-built apps.

Building a REST API in Mythex

You can ask Mythex for an API as part of your app or as its own service. The docs recipe REST API backend has a starter prompt: name your framework and routes, ask for clear JSON errors, keep secrets in environment variables, and include a Dockerfile. Container backends in Node, Python, C#, Java and others publish through a Dockerfile, and Mythex handles the deploy from Publish (API backends). A project can run a website and an API server side by side, and you can switch between them in the preview. Store keys as project secrets, and if the API needs a database, ask for one in chat. For scheduled work around your API, see how to run background jobs.

Questions

What is a REST API?

A REST API is a way for programs to work with your app's data over HTTP. Each kind of data is a resource with its own URL, such as /orders, and standard methods act on it: GET to read, POST to create, PATCH or PUT to update, and DELETE to remove. Data is usually sent as JSON.

Which language should I build a REST API in?

Use what you or your team can maintain. Node.js with Express or Fastify, Python with FastAPI, and C# or Java frameworks all work well. The design rules for routes, status codes, validation and authentication matter more than the language.

How do I secure a REST API?

Require authentication on every non-public route, check on the server that the caller may access each specific record, validate all input, use HTTPS, rate-limit requests, and keep secrets in environment variables. Never trust IDs or roles sent by the client.

Do I need a separate backend for a REST API?

Not always. Frameworks like Next.js can serve API routes alongside pages. A separate API service makes sense when several clients (web, mobile, partners) use it, or when it needs its own language or scaling.

Keep reading

  • How to Add a Blog to Your Website: Options, SEO and Setup — How to add a blog to your website: Markdown files vs a built-in editor vs a CMS, subfolder vs subdomain, SEO basics, and prompts to build it with AI.
  • How to Add a Contact Form to Your Website (That Actually Reaches You) — How to add a contact form that works: save messages, get email alerts, stop spam, and avoid the mistakes that silently lose enquiries. Prompts included.
  • How to Add a Database to Your App (Without Losing Data Later) — How to add a database to an app you built: when you need one, Postgres vs hosted options, designing tables, prompts to use, and mistakes that lose data.
  • How to Add AI Features to Your App — Add summaries, chat, data extraction and classification to your app with an LLM API — keeping keys safe, costs under control and output trustworthy.
  • How to Add Analytics to Your App: GA4, Privacy-First Tools and Product Analytics — How to add analytics to your website or app: Google Analytics 4 vs privacy-first vs product analytics, what to track, cookie consent, and prompts to use.
  • How to Add Cookie Consent to Your Website — Add a cookie banner that actually blocks scripts until people agree: what needs consent, CMP vs custom, Google consent mode and a checklist. Not legal advice.

Start building free · Templates · Docs