Skip to content
Free tool

VAPID key generator and checker

Make the key pair web push needs, check that two keys belong together, and find why a push service answers 403. Everything runs in this page with Web Crypto; nothing you make or paste is sent anywhere.

1. Make a key pairP-256, as RFC 8292 requires. The same format web-push generate-vapid-keys prints.
2. Do these two keys belong together?Signs a test message with the private key and verifies it with the public key.
3. Check a VAPID header (the usual cause of a 403)Paste the Authorization header your server sends, and optionally the subscription endpoint and the public key the page subscribed with.
For developers

What each check means

  • Signature: the JWT must be signed (ES256) with the private key of the public key in k=. A pair that does not belong together fails here.
  • Subscription key: k= must be the same key the page passed as applicationServerKey. New keys on the server and old subscriptions in the database is the most common 403.
  • aud: the origin of the endpoint, such as https://fcm.googleapis.com or https://web.push.apple.com. Not your site, not the full endpoint URL.
  • exp: Unix time in seconds, in the future, at most 24 hours ahead. Milliseconds or a slow server clock fail.
  • sub: a mailto: or https: contact. Apple's push service rejects a missing or malformed one.

Every status code a push service can return is in web push errors; iPhone specifics in web push on iOS. Send a real push to this browser with the web push tester. SignOps Push makes and keeps the VAPID keys for your app, so they never change under your subscriptions.

Frequently asked questions

More questions? Email us and the answer goes on this page.

hello@signops.dev
What are VAPID keys?
A P-256 elliptic curve key pair that identifies your server to push services (RFC 8292). The page passes the public key as applicationServerKey when it subscribes; your server signs a short JWT with the private key on every push. The push service accepts the push only if the signature matches the key the subscription was made with.
Are the keys sent anywhere?
No. They are made and checked with the browser's own Web Crypto API in this page. Nothing you generate or paste here leaves the page. Still, treat a private key you paste into any web page as you would a password, and make a new pair for production if in doubt.
Why does web push return 403 Forbidden?
The VAPID authentication failed: the private key that signed the JWT is not the pair of the public key the page subscribed with, the JWT's exp is in the past or more than 24 hours ahead, aud is not the push service's origin, or sub is not a mailto: or https: value. Paste the header into the checker on this page to see which.
Can I change my VAPID keys?
Only by subscribing every user again. Each existing subscription stays bound to the old public key and returns 403 when signed with a new private key. Make one pair per site and keep it.
What format does the web-push library want?
The public key as the base64url string of the 65-byte uncompressed point (it starts with B) and the private key as the base64url string of the 32-byte private value. Those are the two strings this page makes, and the same ones web-push generate-vapid-keys prints.

Web push without managing keys.

SignOps makes your VAPID keys, encrypts and signs every push, and removes dead subscriptions. Android and iOS from the same call.