curl -X PUT https://api.bouncy.ai/v1/websites/johndoe \
-H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"profile": { "name": "John Doe", "bio": "Now with a new shop" },
"links": [
{ "id": "l1", "type": "simple", "title": "My Website", "url": "https://johndoe.com" },
{ "type": "simple", "title": "Shop", "url": "https://shop.johndoe.com" }
],
"settings": { "deepLinkBehavior": "conservative" }
}
}'
const current = await (await fetch('https://api.bouncy.ai/v1/websites/johndoe', {
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
})).json();
current.data.links.push({ type: 'simple', title: 'Shop', url: 'https://shop.johndoe.com' });
const response = await fetch('https://api.bouncy.ai/v1/websites/johndoe', {
method: 'PUT',
headers: {
'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ data: current.data })
});
const result = await response.json();
console.log(result.message);
import requests
headers = {'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY'}
current = requests.get('https://api.bouncy.ai/v1/websites/johndoe', headers=headers).json()
current['data']['links'].append({'type': 'simple', 'title': 'Shop', 'url': 'https://shop.johndoe.com'})
response = requests.put(
'https://api.bouncy.ai/v1/websites/johndoe',
headers={**headers, 'Content-Type': 'application/json'},
json={'data': current['data']}
)
print(response.json()['message'])
{
"success": true,
"message": "Website updated successfully",
"id": "johndoe",
"deployment": { "skipped": true, "reason": "No custom domain" },
"updatedFields": ["hideBranding", "websiteData", "websiteHtml", "googleTags", "metaPixel", "templateId", "behavior", "title", "description", "backgroundMedia", "socialLinks", "customLinks", "geoRules", "settings"]
}
{
"error": "customSlug cannot be changed with this endpoint. A website's address is fixed; duplicate it to a new address instead.",
"code": "ADDRESS_CHANGE_NOT_SUPPORTED",
"field": "customSlug"
}
{
"error": "Website not found or you do not have permission to update it"
}
Websites
Update Website
Save new content for an existing link-in-bio page
PUT
/
v1
/
websites
/
{websiteId}
curl -X PUT https://api.bouncy.ai/v1/websites/johndoe \
-H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"profile": { "name": "John Doe", "bio": "Now with a new shop" },
"links": [
{ "id": "l1", "type": "simple", "title": "My Website", "url": "https://johndoe.com" },
{ "type": "simple", "title": "Shop", "url": "https://shop.johndoe.com" }
],
"settings": { "deepLinkBehavior": "conservative" }
}
}'
const current = await (await fetch('https://api.bouncy.ai/v1/websites/johndoe', {
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
})).json();
current.data.links.push({ type: 'simple', title: 'Shop', url: 'https://shop.johndoe.com' });
const response = await fetch('https://api.bouncy.ai/v1/websites/johndoe', {
method: 'PUT',
headers: {
'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ data: current.data })
});
const result = await response.json();
console.log(result.message);
import requests
headers = {'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY'}
current = requests.get('https://api.bouncy.ai/v1/websites/johndoe', headers=headers).json()
current['data']['links'].append({'type': 'simple', 'title': 'Shop', 'url': 'https://shop.johndoe.com'})
response = requests.put(
'https://api.bouncy.ai/v1/websites/johndoe',
headers={**headers, 'Content-Type': 'application/json'},
json={'data': current['data']}
)
print(response.json()['message'])
{
"success": true,
"message": "Website updated successfully",
"id": "johndoe",
"deployment": { "skipped": true, "reason": "No custom domain" },
"updatedFields": ["hideBranding", "websiteData", "websiteHtml", "googleTags", "metaPixel", "templateId", "behavior", "title", "description", "backgroundMedia", "socialLinks", "customLinks", "geoRules", "settings"]
}
{
"error": "customSlug cannot be changed with this endpoint. A website's address is fixed; duplicate it to a new address instead.",
"code": "ADDRESS_CHANGE_NOT_SUPPORTED",
"field": "customSlug"
}
{
"error": "Website not found or you do not have permission to update it"
}
A PUT is a full save of the page, handled like saving in the dashboard editor: the page is re-rendered with the dashboard’s generator (every template, live bio tags, analytics tags), paid-only features are removed for free accounts, link ids stay stable so analytics keep adding up, and a custom-domain page is redeployed so the live site changes straight away.
data replaces the page content. Read the current page with GET /v1/websites/, change what you need, and send the whole object back.Request
Headers
string
required
Must be
application/jsonPath Parameters
string
required
The website’s id, slug or custom domainExample:
johndoeBody
object
required
The complete editor data for the page (the
data object returned by Get Website, edited). Links keep their id; new links without one get an id automatically.On free accounts these are removed before publishing, as in the dashboard: hideBranding, profile.verified, contact collection blocks, socialsAppearance.showFollowers and the Smart 18+ mode.string
Switch the design (see Create Website for the list). Defaults to the current design. While the page runs an A/B test (
abTestEnabled in Get Website) the design can only be switched in the editor: a different value returns 400 with code: "AB_TEST_ACTIVE", and a save updates the main design (variation A) only.string
Redirect behavior. Defaults to
data.settings.deepLinkBehavior, then the current value. Free plans are saved as conservative.array
Geo rules for the page. Defaults to
data.settings.geoRules.boolean
default:"true"
Custom-domain pages are redeployed after every save, like the dashboard. Send
false to save without redeploying (the live page then stays on its previous version until the next save). Pages on bouncy.ai and system domains are always live immediately.A website’s address cannot be changed here.
customSlug, customDomain, customPath, isSystemDomain and systemDomain may be sent (the editor re-sends them), but a value that differs from the stored one returns 400 with code: "ADDRESS_CHANGE_NOT_SUPPORTED". Use Duplicate Website to publish the page at a new address.Response
boolean
Whether the page was saved
string
Website ID
string
Success message
object
Custom-domain redeploy result:
{ "success": true, "domain": "..." }, { "success": false, "domain": "...", "error": "..." } (the save itself still succeeded), or { "skipped": true, "reason": "..." }array
Stored fields written by this save
curl -X PUT https://api.bouncy.ai/v1/websites/johndoe \
-H "Authorization: Bearer bcy_live_pk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"profile": { "name": "John Doe", "bio": "Now with a new shop" },
"links": [
{ "id": "l1", "type": "simple", "title": "My Website", "url": "https://johndoe.com" },
{ "type": "simple", "title": "Shop", "url": "https://shop.johndoe.com" }
],
"settings": { "deepLinkBehavior": "conservative" }
}
}'
const current = await (await fetch('https://api.bouncy.ai/v1/websites/johndoe', {
headers: { 'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY' }
})).json();
current.data.links.push({ type: 'simple', title: 'Shop', url: 'https://shop.johndoe.com' });
const response = await fetch('https://api.bouncy.ai/v1/websites/johndoe', {
method: 'PUT',
headers: {
'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ data: current.data })
});
const result = await response.json();
console.log(result.message);
import requests
headers = {'Authorization': 'Bearer bcy_live_pk_YOUR_API_KEY'}
current = requests.get('https://api.bouncy.ai/v1/websites/johndoe', headers=headers).json()
current['data']['links'].append({'type': 'simple', 'title': 'Shop', 'url': 'https://shop.johndoe.com'})
response = requests.put(
'https://api.bouncy.ai/v1/websites/johndoe',
headers={**headers, 'Content-Type': 'application/json'},
json={'data': current['data']}
)
print(response.json()['message'])
{
"success": true,
"message": "Website updated successfully",
"id": "johndoe",
"deployment": { "skipped": true, "reason": "No custom domain" },
"updatedFields": ["hideBranding", "websiteData", "websiteHtml", "googleTags", "metaPixel", "templateId", "behavior", "title", "description", "backgroundMedia", "socialLinks", "customLinks", "geoRules", "settings"]
}
{
"error": "customSlug cannot be changed with this endpoint. A website's address is fixed; duplicate it to a new address instead.",
"code": "ADDRESS_CHANGE_NOT_SUPPORTED",
"field": "customSlug"
}
{
"error": "Website not found or you do not have permission to update it"
}