A mock JWT API that issues real, expiring tokens

Build login, token storage and 401 handling before your auth service exists. MockLab signs real JWTs inside your mock responses, and protected endpoints verify them the way a real API would.

Free while in beta. No credit card required.

Why a hardcoded token isn't enough

Most mock servers return the same token string on every login, and every other endpoint accepts anything you send. Your app looks like it works, but nothing has tested what happens when a token is missing, wrong or expired.

Those are the paths that break in production: the interceptor that never attaches the header, the refresh that loops forever, the user who is never sent back to the sign-in screen.

1. Return real tokens from a mock login

Create a POST /auth/login endpoint and put the token macros wherever your app expects them. Everything else in the response is yours: the user object, roles, permissions, any field your frontend reads.

Response body of POST /auth/login
{
  "accessToken": "{{$jwt.access:15m}}",
  "refreshToken": "{{$jwt.refresh:7d}}",
  "tokenType": "Bearer",
  "expiresIn": 900,
  "user": { "id": "usr_01", "name": "Ada Lovelace", "role": "admin" }
}

2. Protect your other endpoints

Turn on authentication for an endpoint and choose "MockLab Dynamic JWT". From then on, every request is checked:

  • No Authorization header: 401 "Missing Bearer token"
  • A made-up token, or one from another project: 401 "Invalid dynamic JWT signature" / "Token does not match project scope"
  • An expired token: "Token Expired", so your refresh logic has something real to react to
  • A valid token from your login endpoint: your normal response

3. Try it with curl

Terminal
curl -X POST https://api.mocklab.studio/mock/your-project/auth/login
# → { "accessToken": "eyJhbGciOiJIUzI1NiIs…", … }

curl https://api.mocklab.studio/mock/your-project/auth/me
# → 401 { "error": "Unauthorized", "message": "Missing Bearer token for Dynamic JWT" }

curl https://api.mocklab.studio/mock/your-project/auth/me -H "Authorization: Bearer <accessToken>"
# → 200 { "id": "usr_01", "name": "Ada Lovelace", … }

Test expiry and refresh without waiting 15 minutes

Use a short lifetime while you work on refresh logic, for example {{$jwt.access:30s}}. Add a POST /auth/refresh endpoint that returns a fresh {{$jwt.access:15m}}, and watch your interceptor swap tokens and retry the failed request.

Supported units are s, m, h, d, w and y.

Frequently asked questions

Are these real JWTs?

Yes. They are standard signed JWTs with a real expiry, so you can decode them in any JWT debugger. They are signed with a MockLab key, so your app should not verify the signature itself; the protected mock endpoints do that.

Can I put custom claims in the token?

Not yet. The token payload contains the project and the token type. Put user data, roles and permissions in the response body next to the token, which is where most apps read them from anyway.

What does a rejected request return?

The status code you set on the endpoint (401 by default) and a JSON error that says why: missing token, invalid signature, wrong project or expired.

Is MockLab free?

Yes, MockLab is free while it is in beta. No credit card required.

Stop waiting on the backend

Create your first endpoint in under a minute. It's live at a public URL as soon as you save it.

More ways to use MockLab