curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"publishable_key": "pk_live_example",
"secret_key": "sk_live_example",
"webhook_secret": "whsec_example"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys"
payload = {
"publishable_key": "pk_live_example",
"secret_key": "sk_live_example",
"webhook_secret": "whsec_example"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
publishable_key: 'pk_live_example',
secret_key: 'sk_live_example',
webhook_secret: 'whsec_example'
})
};
fetch('https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'publishable_key' => 'pk_live_example',
'secret_key' => 'sk_live_example',
'webhook_secret' => 'whsec_example'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys"
payload := strings.NewReader("{\n \"publishable_key\": \"pk_live_example\",\n \"secret_key\": \"sk_live_example\",\n \"webhook_secret\": \"whsec_example\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"publishable_key\": \"pk_live_example\",\n \"secret_key\": \"sk_live_example\",\n \"webhook_secret\": \"whsec_example\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"publishable_key\": \"pk_live_example\",\n \"secret_key\": \"sk_live_example\",\n \"webhook_secret\": \"whsec_example\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Live mode API keys configured successfully. Test keys have been backed up.",
"live_keys_configured": true,
"webhook_migrated": false
}{
"error": {
"code": "stripe_tracking_account_mismatch",
"message": "Restore the previous Stripe account's key before removing its payment tracking.",
"details": {}
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"error": {
"code": "stripe_tracking_setup_unavailable",
"message": "Stripe is temporarily unavailable. Try configuring live keys again later.",
"details": {}
}
}Configure live Stripe keys
Switches the app to live mode using live Stripe keys you already have from the Stripe dashboard, sent directly in the request body, rather than keys Base44 creates for you. Use Provision live Stripe keys instead to have Base44 create them automatically once the sandbox’s Stripe account is activated.
Stores the keys, backs up the current test credentials, and redeploys backend functions with the updated secrets.
Base44 checks the key prefixes and retrieves the secret key’s Stripe account. When that account differs from the sandbox’s installed live account, Base44 registers a separately signed webhook for payment analytics before storing the keys. The secret key needs account read and webhook management permissions for this setup. Base44 doesn’t verify that the publishable key belongs to the same account or that the account can process payments.
Automatic migration of an existing app-function webhook remains best effort.
If retiring the previous analytics destination fails, the new keys may already be stored. Retry the same configuration to finish the pending setup.
Requires write access to the app. Workspace viewers cannot call this operation.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"publishable_key": "pk_live_example",
"secret_key": "sk_live_example",
"webhook_secret": "whsec_example"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys"
payload = {
"publishable_key": "pk_live_example",
"secret_key": "sk_live_example",
"webhook_secret": "whsec_example"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
publishable_key: 'pk_live_example',
secret_key: 'sk_live_example',
webhook_secret: 'whsec_example'
})
};
fetch('https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'publishable_key' => 'pk_live_example',
'secret_key' => 'sk_live_example',
'webhook_secret' => 'whsec_example'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys"
payload := strings.NewReader("{\n \"publishable_key\": \"pk_live_example\",\n \"secret_key\": \"sk_live_example\",\n \"webhook_secret\": \"whsec_example\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"publishable_key\": \"pk_live_example\",\n \"secret_key\": \"sk_live_example\",\n \"webhook_secret\": \"whsec_example\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/payments/stripe/configure-live-keys")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"publishable_key\": \"pk_live_example\",\n \"secret_key\": \"sk_live_example\",\n \"webhook_secret\": \"whsec_example\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Live mode API keys configured successfully. Test keys have been backed up.",
"live_keys_configured": true,
"webhook_migrated": false
}{
"error": {
"code": "stripe_tracking_account_mismatch",
"message": "Restore the previous Stripe account's key before removing its payment tracking.",
"details": {}
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"error": {
"code": "stripe_tracking_setup_unavailable",
"message": "Stripe is temporarily unavailable. Try configuring live keys again later.",
"details": {}
}
}Authorizations
Personal access token, sent as Authorization: Bearer <token>. Each operation lists the permission it needs: read_only or full_access. A full-access token can call every operation. A read-only token can call only the operations that list read_only; anything else returns 403 read_only_credential_route_not_allowed.
Path Parameters
ID of the Base44 app.
Body
Request to configure live mode API keys.
Live Stripe publishable key beginning with pk_live_.
"pk_live_example"
Live Stripe secret or restricted key beginning with sk_live_ or rk_live_.
"sk_live_example"
Live webhook signing secret beginning with whsec_. Defaults to null, which attempts automatic migration when an existing webhook secret is present.
"whsec_example"
Response
The operation result.
The result of storing live Stripe credentials.
Whether live keys were stored and the app was switched to live mode.
true
Human-readable configuration result.
"Live mode API keys configured successfully. Test keys have been backed up."
Whether the stored completion flag was confirmed. It can be false even after keys were stored if finalization failed.
true
Whether this call automatically migrated the webhook. It is false when a webhook secret was supplied directly.
false
Was this page helpful?