Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Migrate to direct webhook response


Migrate to direct webhook response

Learn how to migrate Issuing real-time authorizations from deprecated API calls to direct webhook responses.

Respond directly to an issuing_authorization.request webhook with a real-time authorization decision instead of making an API call to the deprecated approve and decline endpoints during webhook processing. Responding directly to the webhook event simplifies real-time authorizations and removes an extra API call that can reduce your authorization rate because of timeouts.

If you’re building a new integration, use direct webhook responses. If you have an existing integration that uses the /approve and /decline API calls, migrate it to direct webhook responses.

Note

This guide only applies if you use the /approve and /decline endpoints for real-time authorizations.

Legacy API call flow

Previously, you needed to make an API call to /approve or /decline to make a decision for an incoming authorization request before responding to the issuing_authorization.request webhook.

New direct webhook response flow

You can now respond directly to the issuing_authorization.request webhook with a decision in the response body, without needing to make a separate API call. After the decision, an issuing_authorization.created or issuing_authorization.updated webhook event is still sent.

Learn more about this API in the real-time authorization documentation, and build an integration with our interactive guide.

You must respond with an HTTP status code of 200, a Stripe-Version header set to a specific API version, and a Boolean of approved in the JSON body. The JSON body must correspond with the specified API version.

For controllable amount authorizations, partial approvals optionally include amount.

Direct webhook Authorization API changes

For direct webhook response Authorizations, we’ve made several additions:

  • Added value webhook _ error to request_history.reason . This value is present if the webhook response fails due to validation errors.
  • New field request _ history. reason _ message , which includes a detailed error message if the request _ history. reason is webhook _ error .

Migrate to direct response

You can try the direct webhook response in testing environments. As a best practice, we recommend gradually shifting over from the legacy API call to responding directly to the webhook.

If you call an API method and include the direct webhook response body, the API method decision takes priority.

Here’s an example of what a migration to the direct webhook might look like in Ruby. For other languages, see our interactive guide.

# User's existing API call webhook handling code, using Sinatra.
# In this example, the synchronous webhook and normal webhook share an endpoint.
client = Stripe::StripeClient.new(ENV.fetch('STRIPE_API_KEY'))
post '/webhook' do
 payload = request.body.read

 if event['type'] == 'issuing_authorization.request'
 auth = event['data']['object']
 # Approve with legacy API call.
 client.v1.issuing.authorizations.approve(auth["id"])
 status 200
 elsif event['type'] == 'issuing_authorization.created'
 auth = event['data']['object']
 # If approved, will print "webhook_approved"
 puts "#{auth["request_history"][-1]["reason"]}"
 status 200
 end
end

After testing in a sandbox environment, gradually shift traffic to the direct webhook response.

Last verified 2026-09-24

Is this helpful?