Stripe API Tester

A free Stripe API tester that runs in your browser. The request below is pre-filled to read your balance, a harmless call that proves a key works. Use a test-mode key, the kind that starts sk_test_: it cannot move real money, and it is the only kind you should paste into a third-party tool. Stripe's API has two habits that differ from most — request bodies are form-encoded, not JSON, and errors come with unusually precise detail — and both are explained below.

Query parameters are appended to the URL when the request is sent.

For a POST, add Content-Type: application/x-www-form-urlencoded. An Idempotency-Key header makes a POST safe to retry.

Sent as Authorization: Bearer <token> — the scheme the Stripe API expects.

Base64-encoded and sent as Authorization: Basic.

Credentials are used only to sign this request. They are never logged or stored.

Stripe expects form-encoded fields here, not JSON: name=value pairs joined with &. The body is ignored for GET requests.

No request sent yet.
Open the Auth tab, paste your key, and press Send.

See what an unauthenticated response looks like: — that one deliberately fails, so you can compare it with a successful call. Ctrl+Enter also sends.

Read this before you paste a live API key

  • Your request, key included, is relayed through api-tester.com's server. Browsers block a web page from reading another origin's response unless that origin opts in, and Stripe's API does not opt in for arbitrary sites. A browser-based tester therefore has to hand the request to a server and return the result. Ours is that server, so your key passes through our infrastructure on the way to Stripe.
  • Keys are not logged or stored by us. The credential signs the outbound request and is then gone; your request history stays in your own browser's local storage and is never uploaded. That is a commitment rather than something you can verify from outside, and you are entitled to treat it accordingly.
  • Use a test-mode key only. A key that starts sk_test_ or rk_test_ works on separate test data and cannot touch real payments. A live secret key can refund, pay out and read customer data, and must never be pasted into a third-party tool, this one included.
  • If you are unsure about a key, rotate it. Deleting a key and creating a replacement takes a minute. Any key you have pasted into a third-party tool and feel uneasy about should simply be replaced.

If none of this sits right for a particular credential, build the request here with the key field empty, press Copy as cURL, and add the key on your own machine. You get the exact request and the secret never leaves your laptop.

How to test a Stripe API key

1. Find your test-mode key

Stripe gives every account separate credentials for testing. In the Dashboard, switch to test mode or a sandbox, open the API keys page under Developers, and reveal the secret key. The prefix tells you what you are holding:

PrefixKind of keyPaste it here?
sk_test_Secret key, test modeYes
rk_test_Restricted key, test modeYes — the best choice
pk_test_, pk_live_Publishable key, for Stripe.js in a browserIt will not authenticate most API calls
sk_live_, rk_live_Live keys with access to real paymentsNo

A restricted key is one you create with chosen permissions, for example read-only access to customers and nothing else. It is the right credential for any single-purpose integration, and for experiments like this one.

2. Use the balance endpoint as your probe

The request pre-filled above is a GET to https://api.stripe.com/v1/balance. It changes nothing and needs no parameters. A standard secret key can always call it; a restricted key needs read access to Balance, and answers 403 without it.

3. Send the key as a bearer token

The Auth tab is already set to Bearer token; paste the key into the field. Stripe also accepts HTTP Basic authentication with the key as the username and an empty password, which is what curl -u sk_test_…: sends. Both reach the same result; the API key guide shows the forms side by side.

4. Send and read the response

A 200 with an object whose object field is "balance" means the key works. Check livemode in the body: it should be false. If it is true, you have pasted a live key; roll it in the Dashboard.

Valid key vs invalid key: what you'll see

GET https://api.stripe.com/v1/balance
Authorization: Bearer sk_test_…

200 OK → { "object": "balance", "livemode": false,
           "available": [ { "amount": 0, "currency": "usd", … } ],
           "pending":   [ { "amount": 0, "currency": "usd", … } ] }

401    → { "error": { "type": "invalid_request_error",
                       "message": "Invalid API Key provided: sk_test_****…" } }

Amounts are integers in the currency's smallest unit, so 4900 in usd is $49.00, not $4,900. A few currencies, the Japanese yen among them, have no smaller unit, and there 4900 is ¥4,900. Getting this wrong by a factor of a hundred is the classic first Stripe bug.

Stripe request bodies are form-encoded, not JSON

Stripe's /v1 endpoints return JSON and do not accept it. A request body must be application/x-www-form-urlencoded, the format an HTML form submits. Sending JSON is the most common reason a first POST fails, and the error — a 400 complaining about an unknown parameter — does not make the cause obvious.

POST https://api.stripe.com/v1/customers
Authorization: Bearer sk_test_…
Content-Type: application/x-www-form-urlencoded
Idempotency-Key: 5f1d0c7e-8a2b-4c39-9d41-1b6e2f3a7c55

email=ada%40example.com&name=Ada+Lovelace&metadata[plan]=trial

Nested objects use square brackets — metadata[plan]=trial — and arrays use an index or empty brackets, as in expand[]=customer. Values must be percent-encoded: the @ in an email address becomes %40, and the URL encoder will do it for you. To run this in the console, set the method to POST, add the Content-Type header in the Headers tab, and put the line of fields in the Body tab. The curl form POST example gives the command-line equivalent.

Idempotency keys

A POST that times out leaves you not knowing whether the customer or the charge was created. Stripe solves this with the Idempotency-Key header: send a unique value, such as a UUID, and repeat the same value when you retry. Stripe returns the saved result of the first attempt instead of acting twice. Reusing a key with different parameters is an error. The idempotency guide explains the pattern, which Stripe did much to popularise.

Reading Stripe errors

Stripe's error object is more specific than most, and using all of it saves time.

FieldTells you
typeThe category: invalid_request_error, card_error, idempotency_error or api_error
codeThe specific reason, such as resource_missing or parameter_unknown
paramWhich parameter was at fault
decline_codeFor card errors, the issuer's reason, such as insufficient_funds
messageA sentence for developers. For card errors it is safe to show to the customer
doc_urlA link to the documentation for that code
StatusMeaning on this API
400A required parameter is missing or a value is invalid
401No valid API key was provided
402The parameters were valid and the request failed, most often a declined card
403The key lacks permission — the usual result of a restricted key doing its job
404The object does not exist, or exists in the other mode
409The request conflicts with another, often a reused idempotency key
429Too many requests too quickly; back off exponentially
5xxA fault on Stripe's side. Retry with the same idempotency key

The 404 row hides a frequent confusion. Test mode and live mode hold entirely separate objects. A customer ID created with a live key does not exist as far as a test key is concerned, so asking for it returns resource_missing — and the message says which mode the object was found in when Stripe can tell.

Stripe test cards

In test mode no real card is ever charged. Stripe publishes card numbers that simulate particular outcomes; use any future expiry date and any three-digit security code with them.

Card numberResultTest payment method
4242 4242 4242 4242Payment succeedspm_card_visa
4000 0000 0000 0002Declined, generic declinepm_card_chargeDeclined
4000 0000 0000 9995Declined, insufficient fundspm_card_chargeDeclinedInsufficientFunds
4000 0025 0000 3155Requires 3D Secure authenticationpm_card_authenticationRequired

The numbers are for typing into a payment form built with Stripe's own Elements or Checkout. When you call the API directly, as from this console, do not send card numbers at all: Stripe blocks raw card data on most accounts, for compliance reasons. Pass the matching test payment method instead, for example payment_method=pm_card_visa when creating a PaymentIntent. Stripe's testing documentation lists many more cards, by brand, country and failure type.

From API calls to webhooks

Most Stripe integrations are half requests and half events: you create a payment with the API, and Stripe tells you the outcome with a webhook. The /v1/events endpoint in the list beside the console returns the same event objects a webhook delivers, which makes it a convenient way to look at a real payload. The Stripe webhook example shows the headers and how the Stripe-Signature value is checked, and the webhook tester gives you a temporary URL to receive one.

Provider APIs change — check the official docs

api-tester.com is an independent tool with no affiliation to, partnership with or endorsement from Stripe. Nothing here is official documentation. Endpoints, model names, error wording and limits are the provider's to change, and this page can fall behind. For current and authoritative detail, consult the official Stripe API reference.

Stripe versions its API by date, and behaviour depends on the version your account or your Stripe-Version header selects. The test card numbers above are the long-standing ones from Stripe's testing documentation; confirm them there before building a test suite on them.

Test other providers and related tools

Frequently asked questions

How do I test whether my Stripe API key is valid?

Send a GET request to https://api.stripe.com/v1/balance with the key in an Authorization header using the Bearer scheme. A valid key returns 200 and a balance object. An invalid one returns 401 with an error message that quotes a redacted form of the key.

What is the difference between sk_test and sk_live keys?

A key starting sk_test_ works on test data: no real money moves and no real cards are charged. A key starting sk_live_ acts on real payments and customers. The two modes share endpoints and keep completely separate objects.

Why does Stripe reject my JSON request body?

Because the v1 API accepts only form-encoded bodies. Send Content-Type: application/x-www-form-urlencoded and write the parameters as name=value pairs joined with ampersands, using square brackets for nested fields. Responses are JSON.

What is the Stripe test card number?

4242 4242 4242 4242 is the standard test Visa that always succeeds, with any future expiry date and any three-digit CVC. Other numbers simulate declines and authentication. They work only in test mode.

Is it safe to paste my Stripe key here?

Only a test-mode key. The request is relayed through api-tester.com's server, so the key transits our infrastructure on the way to Stripe. We do not log or store keys, but a live secret key should never be given to any third-party tool. To keep even a test key local, build the request here without it, copy it as cURL and add the key on your own machine.

Is this tool affiliated with Stripe?

No. api-tester.com is an independent HTTP request console with no affiliation to, partnership with or endorsement from Stripe. Check the official Stripe documentation for current endpoints and behaviour.