Replit gives you two built-in terminals for testing APIs without leaving your browser: the Shell for running curl commands and the Console for viewing server output. You can test any endpoint by running curl in Shell, or by writing quick fetch scripts and executing them directly. This tutorial covers testing GET, POST, and authenticated endpoints, validating JSON responses, and debugging common API errors.
Test API Endpoints Directly in Replit Using Shell and Console
When building backend APIs in Replit, you need a fast way to verify your endpoints work correctly before connecting a frontend. Instead of switching to external tools like Postman, you can use Replit's built-in Shell to run curl commands and write quick test scripts. This tutorial shows you how to test GET, POST, PUT, and DELETE endpoints, pass headers and authentication tokens, validate JSON responses, and read server logs in the Console pane.
Prerequisites
- A Replit account with an active App
- A running backend server (Express, Flask, FastAPI, or similar)
- Basic understanding of HTTP methods (GET, POST, PUT, DELETE)
- Familiarity with JSON format
Step-by-step guide
Start your server and open Shell alongside Console
Start your server and open Shell alongside Console
Press the Run button to start your backend server. The Console pane will show your server's startup output, including the port it is listening on. Next, open a Shell tab by clicking Tools in the left sidebar and selecting Shell. Arrange your workspace with the editor on the left, Console in the top-right, and Shell in the bottom-right. This layout lets you edit code, see server logs, and run test commands simultaneously without switching tabs.
Expected result: Your server is running (Console shows 'listening on port 3000' or similar) and Shell is open and ready for commands.
Test a GET endpoint with curl
Test a GET endpoint with curl
In Shell, use curl to send a GET request to your local server. Replit exposes your running app at localhost on the port configured in your .replit file. The -s flag silences progress output, and piping through json_pp (or jq if installed) formats the response for readability. Check that the response status code and body match what you expect. If you get 'Connection refused,' your server may not be running or may be listening on a different port.
1# Test a basic GET endpoint2curl -s http://localhost:3000/api/users | json_pp34# Include response headers to see status code5curl -s -I http://localhost:3000/api/usersExpected result: Shell displays formatted JSON output from your API endpoint with the correct data structure.
Test a POST endpoint with request body and headers
Test a POST endpoint with request body and headers
To test POST endpoints, use curl with the -X POST flag, set the Content-Type header to application/json, and pass a JSON body with the -d flag. This simulates what your frontend or a client application would send. Watch the Console pane for server-side logs that confirm the request was received and processed. If you get a 400 or 422 error, your request body likely does not match the validation schema your server expects.
1# Test a POST endpoint with JSON body2curl -s -X POST http://localhost:3000/api/users \3 -H "Content-Type: application/json" \4 -d '{"name": "Jane Doe", "email": "jane@example.com"}' | json_pp56# Test PUT (update) endpoint7curl -s -X PUT http://localhost:3000/api/users/1 \8 -H "Content-Type: application/json" \9 -d '{"name": "Jane Smith"}' | json_pp1011# Test DELETE endpoint12curl -s -X DELETE http://localhost:3000/api/users/1Expected result: The server responds with a success status (200 or 201) and the created or updated resource in JSON format.
Test authenticated endpoints using Secrets
Test authenticated endpoints using Secrets
For endpoints that require API keys or bearer tokens, store your credentials in Replit Secrets (Tools -> Secrets) and reference them in your curl commands using the $VARIABLE_NAME syntax. Never hardcode API keys or tokens in your Shell history or code files. After adding a secret, you may need to run kill 1 in Shell to restart your environment and make the new secret available as an environment variable.
1# Store your API key in Secrets first, then use it:2curl -s http://localhost:3000/api/protected \3 -H "Authorization: Bearer $API_TOKEN" | json_pp45# Test with an external API using a stored key6curl -s https://api.example.com/data \7 -H "x-api-key: $EXTERNAL_API_KEY" | json_ppExpected result: The authenticated endpoint returns the protected data instead of a 401 Unauthorized error.
Write a reusable test script for multiple endpoints
Write a reusable test script for multiple endpoints
For APIs with many endpoints, create a test script file instead of running individual curl commands. Create a file called test-api.js (or test_api.py for Python) in your project root. Use fetch (built into Node.js 18+) or the requests library in Python to call each endpoint and log the results. Run the script in Shell with node test-api.js. This approach is faster for repeated testing and lets you add assertions to catch regressions.
1// test-api.js — Run with: node test-api.js2const BASE = 'http://localhost:3000/api';34async function testEndpoints() {5 // Test GET /api/users6 const users = await fetch(`${BASE}/users`);7 console.log('GET /users:', users.status, await users.json());89 // Test POST /api/users10 const created = await fetch(`${BASE}/users`, {11 method: 'POST',12 headers: { 'Content-Type': 'application/json' },13 body: JSON.stringify({ name: 'Test User', email: 'test@example.com' })14 });15 console.log('POST /users:', created.status, await created.json());1617 // Test GET /api/users/118 const single = await fetch(`${BASE}/users/1`);19 console.log('GET /users/1:', single.status, await single.json());20}2122testEndpoints().catch(console.error);Expected result: Shell displays the status code and response body for each endpoint, making it easy to verify all routes at once.
Debug failed requests using Console server logs
Debug failed requests using Console server logs
When an API request returns an error, the Console pane shows the server-side perspective. Look for stack traces, validation errors, and database query failures in the Console output. Add structured logging to your server code so every request logs the method, path, status code, and response time. This makes it much easier to correlate a Shell curl command with the server's internal processing. Client-side JavaScript logs appear only in the Preview pane's DevTools, not in Console.
1// Add request logging middleware to Express2app.use((req, res, next) => {3 const start = Date.now();4 res.on('finish', () => {5 console.log(`${req.method} ${req.path} ${res.statusCode} ${Date.now() - start}ms`);6 });7 next();8});Expected result: Every API request logs a line in Console showing the HTTP method, path, status code, and duration.
Complete working example
1// test-api.js — Reusable API endpoint tester2// Run with: node test-api.js34const BASE_URL = 'http://localhost:3000/api';56async function test(method, path, body = null) {7 const options = {8 method,9 headers: { 'Content-Type': 'application/json' }10 };11 if (body) options.body = JSON.stringify(body);1213 try {14 const res = await fetch(`${BASE_URL}${path}`, options);15 const data = await res.json().catch(() => null);16 const status = res.ok ? 'PASS' : 'FAIL';17 console.log(`[${status}] ${method} ${path} -> ${res.status}`);18 if (data) console.log(' Response:', JSON.stringify(data, null, 2));19 return { status: res.status, data };20 } catch (err) {21 console.log(`[ERROR] ${method} ${path} -> ${err.message}`);22 return { status: 0, error: err.message };23 }24}2526async function runTests() {27 console.log('\n--- API Test Suite ---\n');2829 // GET all users30 await test('GET', '/users');3132 // POST create user33 await test('POST', '/users', {34 name: 'Test User',35 email: 'test@example.com'36 });3738 // GET single user39 await test('GET', '/users/1');4041 // PUT update user42 await test('PUT', '/users/1', { name: 'Updated User' });4344 // DELETE user45 await test('DELETE', '/users/1');4647 console.log('\n--- Tests Complete ---\n');48}4950runTests();Common mistakes when testing APIs using Replit
Why it's a problem: Forgetting to set Content-Type header on POST/PUT requests, causing the server to receive an empty body
How to avoid: Always include -H 'Content-Type: application/json' in curl commands that send a request body.
Why it's a problem: Using the Replit preview URL instead of localhost in curl commands, which adds latency and may hit CORS restrictions
How to avoid: Use http://localhost:PORT for testing from Shell. The preview URL is for browser access only.
Why it's a problem: Hardcoding API keys in curl commands or test scripts instead of using Secrets
How to avoid: Store all keys in Tools -> Secrets and reference them as $VARIABLE_NAME in Shell or process.env.VARIABLE_NAME in code.
Why it's a problem: Looking for client-side console.log output in the Console pane instead of the Preview pane DevTools
How to avoid: Server-side logs appear in Console. Client-side JavaScript logs appear only in the Preview pane's DevTools (F12).
Why it's a problem: Not restarting the server after changing backend code, so curl hits the old version of the endpoint
How to avoid: Press Stop then Run to restart your server. Alternatively, use a dev server with hot reload like nodemon.
Best practices
- Always test endpoints from Shell before connecting them to a frontend to isolate server issues from client issues
- Store API keys and tokens in Replit Secrets (Tools -> Secrets) and reference them as environment variables in curl commands
- Add request logging middleware to your server so Console shows method, path, status, and duration for every request
- Use json_pp or jq to format JSON responses in Shell so you can quickly spot missing or malformed fields
- Create a test script file for projects with more than three endpoints to save time on repeated testing
- Check Console output immediately after a failed curl request — server-side errors are often more descriptive than the HTTP status code alone
- Run kill 1 in Shell after adding new Secrets to ensure they are loaded into your environment
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am building a REST API in Replit with Express.js. Show me how to test all my CRUD endpoints using curl commands in the Shell. Include examples for GET, POST with JSON body, PUT, and DELETE, plus how to pass an Authorization header stored in Replit Secrets.
Add request logging middleware to my Express server that logs the HTTP method, path, status code, and response time for every request. Also create a test-api.js script that tests all my API endpoints and prints pass/fail results.
Frequently asked questions
You cannot install Postman inside Replit because it is a desktop application. However, you can use curl in Shell, which supports all the same features. For a graphical alternative, use the Postman web app in a separate browser tab and point it at your Replit preview URL.
Your server may be listening on a different port than you are targeting with curl. Check the Console output for the actual port number. Also verify your server binds to 0.0.0.0, not 127.0.0.1, as some frameworks default to localhost only.
Curl does not support WebSocket connections. Install wscat via npm (npm install -g wscat) and connect with wscat -c ws://localhost:3000/ws. Alternatively, write a small Node.js script using the ws library to test WebSocket communication.
Yes. Curl works with any URL, not just localhost. You can test external APIs by running curl -s https://api.example.com/endpoint in Shell. Store any required API keys in Secrets and reference them with $VARIABLE_NAME.
No. Shell commands run in your development workspace, not in the deployed environment. Testing from Shell does not affect deployment quotas, compute units, or request limits.
Use curl -v (verbose mode) to see the complete request and response headers. Use curl -I to see response headers only without the body. Both options help diagnose content-type mismatches and authentication failures.
Use curl's -F flag for multipart form data: curl -X POST http://localhost:3000/upload -F 'file=@photo.jpg'. This sends the file as a multipart upload, which is how browsers send form submissions with file inputs.
Yes. RapidDev's engineering team can help design REST or GraphQL APIs, set up automated testing pipelines, and configure deployment workflows for Replit projects that need professional-grade API infrastructure.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation