# How to test APIs using Replit

- Tool: Replit
- Difficulty: Intermediate
- Time required: 15-20 minutes
- Compatibility: All Replit plans (Starter, Core, Pro). Works with any backend framework (Express, Flask, FastAPI, Django).
- Last updated: March 2026

## TL;DR

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.

## Before you start

- 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

### 1. 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.

### 2. 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.

```
# Test a basic GET endpoint
curl -s http://localhost:3000/api/users | json_pp

# Include response headers to see status code
curl -s -I http://localhost:3000/api/users
```

**Expected result:** Shell displays formatted JSON output from your API endpoint with the correct data structure.

### 3. 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.

```
# Test a POST endpoint with JSON body
curl -s -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Doe", "email": "jane@example.com"}' | json_pp

# Test PUT (update) endpoint
curl -s -X PUT http://localhost:3000/api/users/1 \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Smith"}' | json_pp

# Test DELETE endpoint
curl -s -X DELETE http://localhost:3000/api/users/1
```

**Expected result:** The server responds with a success status (200 or 201) and the created or updated resource in JSON format.

### 4. 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.

```
# Store your API key in Secrets first, then use it:
curl -s http://localhost:3000/api/protected \
  -H "Authorization: Bearer $API_TOKEN" | json_pp

# Test with an external API using a stored key
curl -s https://api.example.com/data \
  -H "x-api-key: $EXTERNAL_API_KEY" | json_pp
```

**Expected result:** The authenticated endpoint returns the protected data instead of a 401 Unauthorized error.

### 5. 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.

```
// test-api.js — Run with: node test-api.js
const BASE = 'http://localhost:3000/api';

async function testEndpoints() {
  // Test GET /api/users
  const users = await fetch(`${BASE}/users`);
  console.log('GET /users:', users.status, await users.json());

  // Test POST /api/users
  const created = await fetch(`${BASE}/users`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name: 'Test User', email: 'test@example.com' })
  });
  console.log('POST /users:', created.status, await created.json());

  // Test GET /api/users/1
  const single = await fetch(`${BASE}/users/1`);
  console.log('GET /users/1:', single.status, await single.json());
}

testEndpoints().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.

### 6. 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.

```
// Add request logging middleware to Express
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    console.log(`${req.method} ${req.path} ${res.statusCode} ${Date.now() - start}ms`);
  });
  next();
});
```

**Expected result:** Every API request logs a line in Console showing the HTTP method, path, status code, and duration.

## Complete code example

File: `test-api.js`

```javascript
// test-api.js — Reusable API endpoint tester
// Run with: node test-api.js

const BASE_URL = 'http://localhost:3000/api';

async function test(method, path, body = null) {
  const options = {
    method,
    headers: { 'Content-Type': 'application/json' }
  };
  if (body) options.body = JSON.stringify(body);

  try {
    const res = await fetch(`${BASE_URL}${path}`, options);
    const data = await res.json().catch(() => null);
    const status = res.ok ? 'PASS' : 'FAIL';
    console.log(`[${status}] ${method} ${path} -> ${res.status}`);
    if (data) console.log('  Response:', JSON.stringify(data, null, 2));
    return { status: res.status, data };
  } catch (err) {
    console.log(`[ERROR] ${method} ${path} -> ${err.message}`);
    return { status: 0, error: err.message };
  }
}

async function runTests() {
  console.log('\n--- API Test Suite ---\n');

  // GET all users
  await test('GET', '/users');

  // POST create user
  await test('POST', '/users', {
    name: 'Test User',
    email: 'test@example.com'
  });

  // GET single user
  await test('GET', '/users/1');

  // PUT update user
  await test('PUT', '/users/1', { name: 'Updated User' });

  // DELETE user
  await test('DELETE', '/users/1');

  console.log('\n--- Tests Complete ---\n');
}

runTests();
```

## Common mistakes

- **Forgetting to set Content-Type header on POST/PUT requests, causing the server to receive an empty body** — undefined Fix: Always include -H 'Content-Type: application/json' in curl commands that send a request body.
- **Using the Replit preview URL instead of localhost in curl commands, which adds latency and may hit CORS restrictions** — undefined Fix: Use http://localhost:PORT for testing from Shell. The preview URL is for browser access only.
- **Hardcoding API keys in curl commands or test scripts instead of using Secrets** — undefined Fix: Store all keys in Tools -> Secrets and reference them as $VARIABLE_NAME in Shell or process.env.VARIABLE_NAME in code.
- **Looking for client-side console.log output in the Console pane instead of the Preview pane DevTools** — undefined Fix: Server-side logs appear in Console. Client-side JavaScript logs appear only in the Preview pane's DevTools (F12).
- **Not restarting the server after changing backend code, so curl hits the old version of the endpoint** — undefined Fix: 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

## Frequently asked questions

### Can I use Postman instead of curl in Replit?

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.

### Why does curl return 'Connection refused' when my server is running?

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.

### How do I test WebSocket endpoints in Replit?

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.

### Can I test external APIs from Replit Shell?

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.

### Does testing from Shell count against my Replit deployment limits?

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.

### How do I see the full request and response headers in curl?

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.

### What if my API requires testing with files or form data?

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.

### Can RapidDev help build and test complex API architectures?

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.

---

Source: https://www.rapidevelopers.com/replit-tutorial/how-to-use-replit-s-interactive-console-to-quickly-test-api-endpoints
© RapidDev — https://www.rapidevelopers.com/replit-tutorial/how-to-use-replit-s-interactive-console-to-quickly-test-api-endpoints
