← Back to Articles         
API Works in Postman but Fails from Angular

API Works in Postman but Fails from Angular

Published on 02 Oct 2026     10 min read Angular
Scenario Based Questions

API Works in Postman but Fails from Angular — What Could Cause This?

This is a very common Angular + ASP.NET Core troubleshooting scenario.

The key clue is:

If the API works in Postman, but fails from Angular running in a browser, first investigate browser-specific behavior and differences between the Angular request and the Postman request.

The most common causes are:

CORS
Wrong API URL
HTTP/HTTPS mixed content
Missing JWT / Authorization header
CORS preflight OPTIONS failure
Different request headers
Different request body
Cookie / credentials configuration
SSL certificate problems
Angular interceptor issues

1. Why Can Postman Work While Angular Fails?

Postman and a browser are not the same environment.

For example:

Postman
   |
   | HTTP Request
   v
ASP.NET Core API
   |
   └── Works

But Angular runs inside a browser:

Angular
   |
   v
Browser
   |
   | Browser security rules
   | CORS
   | Mixed-content rules
   | Cookie rules
   | Preflight OPTIONS
   v
ASP.NET Core API

The browser imposes security restrictions that Postman generally does not.

Therefore:

Postman works
Angular fails

does not necessarily mean Angular code is wrong.


2. First Check — Browser Network Tab

My first troubleshooting step would be:

F12
 ↓
Network
 ↓
Trigger the Angular request
 ↓
Select failed request

Check:

  • Request URL
  • HTTP method
  • Status code
  • Request headers
  • Response headers
  • Request payload
  • Response body
  • OPTIONS request, if present

Also check:

F12
 ↓
Console

The actual error usually tells you which direction to investigate.


3. Cause #1 — CORS

This is one of the most common reasons.

Suppose Angular runs at:

http://localhost:4200

and ASP.NET Core runs at:

https://localhost:7001

These are different origins.

The browser applies CORS rules.

Postman does not enforce browser CORS policy in the same way.

So:

Postman
   ↓
API
   ↓
Works


Angular
   ↓
Browser
   ↓
CORS check
   ↓
Blocked

4. ASP.NET Core CORS Configuration

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddCors(options =>
{
    options.AddPolicy("AngularPolicy", policy =>
    {
        policy
            .WithOrigins("http://localhost:4200")
            .AllowAnyHeader()
            .AllowAnyMethod();
    });
});

var app = builder.Build();

app.UseHttpsRedirection();

app.UseCors("AngularPolicy");

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Now ASP.NET Core explicitly allows requests from:

http://localhost:4200

5. Production CORS

Suppose production Angular is:

https://www.myapp.com

Then production CORS should allow that origin:

.WithOrigins(
    "https://www.myapp.com"
)

Be careful:

https://myapp.com

and

https://www.myapp.com

are different origins.

Likewise:

http://myapp.com

and:

https://myapp.com

are different origins.


6. Cause #2 — Preflight OPTIONS Request Fails

Angular may send a request such as:

POST /api/products
Authorization: Bearer eyJ...
Content-Type: application/json

Before sending it, the browser may send:

OPTIONS /api/products

This is called a CORS preflight request.

Flow:

Angular
   ↓
Browser
   ↓
OPTIONS /api/products
   ↓
ASP.NET Core
   ↓
CORS response
   ↓
Browser permits actual request
   ↓
POST /api/products

If OPTIONS fails:

OPTIONS
   ↓
CORS / proxy / server rejects it
   ↓
Browser blocks request
   ↓
Actual POST may never be sent

Postman may appear to work because it doesn't perform browser CORS preflight enforcement.

How to check

Open:

F12 → Network

Look for:

OPTIONS

If the OPTIONS request fails, investigate CORS and web-server/proxy configuration.


7. Cause #3 — Angular Is Calling the Wrong API URL

Postman might call:

https://api.myapp.com/api/products

while Angular accidentally calls:

https://api.myapp.com/products

or even:

https://localhost:7001/api/products

Check the browser Network tab.

The Request URL should exactly match the expected API endpoint.

For Angular:

export const environment = {
  apiUrl: 'https://api.myapp.com/api'
};

Then:

getProducts() {
  return this.http.get(
    `${environment.apiUrl}/products`
  );
}

8. Cause #4 — Missing JWT Token

Postman may contain:

Authorization: Bearer eyJhbGciOi...

while Angular sends:

GET /api/products

without an Authorization header.

Then ASP.NET Core:

[Authorize]

returns:

401 Unauthorized

9. Check Angular Authorization Header

Open:

F12
 ↓
Network
 ↓
API Request
 ↓
Request Headers

You should see:

Authorization: Bearer eyJhbGciOi...

If not, investigate your Angular interceptor.


10. Angular JWT Interceptor

auth.interceptor.ts

import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn =
  (req, next) => {

    const token =
      localStorage.getItem('access_token');

    if (!token) {
      return next(req);
    }

    const authRequest = req.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });

    return next(authRequest);
  };

Register it:

app.config.ts

import {
  ApplicationConfig
} from '@angular/core';

import {
  provideHttpClient,
  withInterceptors
} from '@angular/common/http';

import {
  authInterceptor
} from './auth.interceptor';

export const appConfig: ApplicationConfig = {

  providers: [

    provideHttpClient(
      withInterceptors([
        authInterceptor
      ])
    )

  ]
};

If you forget:

withInterceptors([
  authInterceptor
])

the interceptor won't execute.


11. Cause #5 — HTTP/HTTPS Mixed Content

Suppose Angular is:

https://www.myapp.com

but API is:

http://api.myapp.com

The browser may block this.

HTTPS Angular
     ↓
HTTP API
     ↓
Mixed-content security restriction
     ↓
Blocked

Postman can still call:

http://api.myapp.com

because it isn't a web page operating under browser mixed-content rules.

Prefer:

https://www.myapp.com
        ↓
https://api.myapp.com

12. Cause #6 — SSL Certificate Problem

Postman and browsers can behave differently depending on certificate validation/settings.

Check:

https://api.myapp.com

directly in the browser.

Look for:

  • expired certificate
  • untrusted certificate
  • hostname mismatch
  • incomplete certificate chain

Production should use a valid trusted HTTPS certificate.


13. Cause #7 — Request Body Is Different

Postman may send:

{
  "name": "Laptop",
  "price": 50000
}

but Angular may accidentally send:

{
  "productName": "Laptop",
  "amount": 50000
}

ASP.NET Core expects:

public class ProductDto
{
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
}

Depending on validation and model-binding configuration, the Angular request could result in:

400 Bad Request

Check

In:

F12 → Network → Payload

compare Angular's request payload with the working Postman request.


14. Cause #8 — Different Headers

Postman might send:

Content-Type: application/json
Authorization: Bearer ...
X-Api-Key: ABC123

Angular might send only:

Content-Type: application/json

If your ASP.NET Core API requires:

X-Api-Key

Angular must send it too.

For example:

const headers = {
  'X-Api-Key': 'ABC123'
};

return this.http.get(url, {
  headers
});

For sensitive production credentials, however, don't embed secret API keys in Angular bundles because browser-delivered code is visible to users.


15. Cause #9 — Cookie Authentication / Credentials

If authentication uses cookies across origins, Angular may need:

this.http.get(url, {
  withCredentials: true
});

ASP.NET Core CORS then needs compatible credential configuration:

builder.Services.AddCors(options =>
{
    options.AddPolicy("AngularPolicy", policy =>
    {
        policy
            .WithOrigins(
                "https://www.myapp.com"
            )
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials();
    });
});

For credentialed CORS, don't combine:

.AllowAnyOrigin()

with:

.AllowCredentials()

Instead, specify the trusted origins explicitly.

Cookie settings such as SameSite and Secure may also matter for cross-site authentication.


16. Cause #10 — Angular Interceptor Changes the Request

Suppose you have multiple interceptors:

provideHttpClient(
  withInterceptors([
    authInterceptor,
    loggingInterceptor,
    errorInterceptor
  ])
)

An interceptor could accidentally:

  • remove headers
  • modify the URL
  • modify the request body
  • handle errors incorrectly
  • attach an invalid/expired token

For example, check that your interceptor clones the request correctly:

const authRequest = req.clone({
  setHeaders: {
    Authorization: `Bearer ${token}`
  }
});

return next(authRequest);

17. Cause #11 — Proxy Configuration

During Angular development you might use:

{
  "/api": {
    "target": "https://localhost:7001",
    "secure": false
  }
}

Then Angular calls:

this.http.get('/api/products');

During development:

Angular
localhost:4200
    ↓
Angular dev proxy
    ↓
localhost:7001
    ↓
API

But the Angular development proxy is not automatically your production proxy.

After:

ng build

the browser still needs a real production route to /api, usually provided by your production web server/reverse proxy, or Angular must use the deployed API URL.

This is a very common deployment mistake.


18. Compare Postman and Angular Side by Side

This is one of the best troubleshooting approaches.

Check Postman Angular
URL /api/products Same?
Method GET/POST Same?
Authorization Bearer token Same?
Content-Type JSON Same?
Custom headers Present Present?
Request body Correct Same?
Cookies Present Sent?
HTTPS Works Browser trusts it?
CORS Not browser-enforced Browser-enforced
Preflight Not browser-enforced May occur

Don't just ask:

"Does Postman work?"

Ask:

"What is different between the successful Postman request and the failing browser request?"

That usually leads directly to the root cause.


19. Status Code Gives You a Clue

Use the actual error to narrow the investigation.

Result Likely area
CORS error CORS configuration
Failed OPTIONS Preflight/CORS/proxy
400 Request payload/validation
401 Authentication/token
403 Authorization
404 Wrong URL/routing
405 HTTP method/proxy/preflight
415 Content-Type
500 API exception
502 Gateway/reverse proxy
Certificate error HTTPS/TLS
Mixed-content error HTTPS frontend → HTTP API

20. Full Simple Example

Assume:

Angular
http://localhost:4200

ASP.NET Core
https://localhost:7001

ASP.NET Core Program.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddCors(options =>
{
    options.AddPolicy("Angular", policy =>
    {
        policy
            .WithOrigins(
                "http://localhost:4200"
            )
            .AllowAnyHeader()
            .AllowAnyMethod();
    });
});

builder.Services
    .AddAuthentication(
        JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters =
            new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,

                ValidIssuer = "MyApi",
                ValidAudience = "MyAngularApp",

                IssuerSigningKey =
                    new SymmetricSecurityKey(
                        Encoding.UTF8.GetBytes(
                            "ThisIsMySuperSecretKey123456789"
                        ))
            };
    });

builder.Services.AddAuthorization();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseCors("Angular");

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Angular auth.interceptor.ts

import {
  HttpInterceptorFn
} from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn =
  (req, next) => {

    const token =
      localStorage.getItem('access_token');

    if (!token) {
      return next(req);
    }

    const authRequest = req.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });

    return next(authRequest);
  };

Angular app.config.ts

import {
  ApplicationConfig
} from '@angular/core';

import {
  provideHttpClient,
  withInterceptors
} from '@angular/common/http';

import {
  authInterceptor
} from './auth.interceptor';

export const appConfig: ApplicationConfig = {

  providers: [

    provideHttpClient(
      withInterceptors([
        authInterceptor
      ])
    )

  ]
};

Angular product.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private apiUrl =
    'https://localhost:7001/api/products';

  constructor(private http: HttpClient) {}

  getProducts() {
    return this.http.get(this.apiUrl);
  }
}

The request becomes:

Angular ProductService
        ↓
authInterceptor
        ↓
Authorization: Bearer <JWT>
        ↓
Browser
        ↓
CORS / Preflight if required
        ↓
ASP.NET Core
        ↓
Authentication
        ↓
Authorization
        ↓
ProductsController

Troubleshooting Flow

A practical troubleshooting sequence is:

Postman works
Angular fails
      ↓
Open F12
      ↓
Network + Console
      ↓
Check exact API URL
      ↓
Check CORS error
      ↓
Check OPTIONS request
      ↓
Check HTTP status
      ↓
Check Authorization header
      ↓
Check request payload
      ↓
Check HTTPS / certificate
      ↓
Compare Angular request
with Postman request

Key Points

When an API works in Postman but fails from Angular, the strongest suspects are browser-specific restrictions or request differences.

Check these first:

  1. CORS
  2. Preflight OPTIONS
  3. Correct API URL
  4. Authorization/JWT header
  5. HTTPS mixed content
  6. SSL certificate
  7. Request body
  8. Content-Type/custom headers
  9. Cookies and withCredentials
  10. Angular interceptors
  11. Development proxy vs production routing

Most importantly:

Postman works
     ≠
Browser must work

Postman success tells you that the endpoint is reachable and can handle that Postman request. It does not prove that browser CORS, preflight, credentials, or Angular's actual request are correct.


Interview Questions and Answers

1. The API works in Postman but fails from Angular. What could cause this?

Interview Answer:

I would first inspect the browser Network and Console tabs. Common causes are CORS, a failed preflight request, an incorrect API URL, missing JWT headers, HTTPS mixed-content restrictions, certificate issues, or differences in headers and request payload between Angular and Postman.


2. Why does CORS affect Angular but not Postman?

Answer:

CORS is primarily a browser-enforced security mechanism for cross-origin web requests.

Angular runs inside the browser, while Postman is an API client and isn't subject to browser CORS enforcement in the same way.


3. What is a preflight request?

Answer:

A preflight is an HTTP:

OPTIONS

request that the browser may send before the actual cross-origin request to determine whether the server permits the requested method and headers.


4. Postman works but Angular returns 401. What would you check?

Answer:

I would compare the Authorization headers.

Angular should normally send:

Authorization: Bearer <JWT>

Then I would verify the Angular authentication interceptor and token validity.


5. Postman works but Angular shows a CORS error. Is the API broken?

Not necessarily.

The API may be functioning correctly, but it has not allowed the Angular application's origin under its CORS policy.


6. Why can Postman call an HTTP API while an HTTPS Angular application cannot?

The browser can block:

HTTPS Angular
     ↓
HTTP API

because it is mixed content.

Postman isn't operating as a script inside an HTTPS web page.


7. What is the best debugging technique in this situation?

Interview Answer:

I would compare the successful Postman request with the failing Angular request—URL, HTTP method, headers, authorization token, content type, cookies, and payload—and also inspect browser-specific issues such as CORS, preflight, and mixed content.

That is the core troubleshooting principle:

Successful Postman Request
            ↕
       Compare
            ↕
Failing Angular Request

→ Find the difference
→ Find the root cause
← Back to Articles