Save organization custom pricing configuration
Requires the path organization to match the authenticated user; an optional body client_id must also match. Saves custom pricing configuration and increments its version under a lifecycle lock. It does not collect or record a payment. Decommissioned organizations are rejected; a temporarily unavailable lock returns409, retryable:true and Retry-After30. Requires permission: one of access_payment_gateways.
curl --request POST \
--url https://api.gratona.com/v1/client/client-custom/{client_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"custom_pricing": {
"enabled": true,
"frequency": 0,
"amount": 299,
"start_date": "2026-11-01"
},
"client_id": 42
}
'import requests
url = "https://api.gratona.com/v1/client/client-custom/{client_id}"
payload = {
"custom_pricing": {
"enabled": True,
"frequency": 0,
"amount": 299,
"start_date": "2026-11-01"
},
"client_id": 42
}
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({
custom_pricing: {enabled: true, frequency: 0, amount: 299, start_date: '2026-11-01'},
client_id: 42
})
};
fetch('https://api.gratona.com/v1/client/client-custom/{client_id}', 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://api.gratona.com/v1/client/client-custom/{client_id}",
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([
'custom_pricing' => [
'enabled' => true,
'frequency' => 0,
'amount' => 299,
'start_date' => '2026-11-01'
],
'client_id' => 42
]),
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://api.gratona.com/v1/client/client-custom/{client_id}"
payload := strings.NewReader("{\n \"custom_pricing\": {\n \"enabled\": true,\n \"frequency\": 0,\n \"amount\": 299,\n \"start_date\": \"2026-11-01\"\n },\n \"client_id\": 42\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://api.gratona.com/v1/client/client-custom/{client_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"custom_pricing\": {\n \"enabled\": true,\n \"frequency\": 0,\n \"amount\": 299,\n \"start_date\": \"2026-11-01\"\n },\n \"client_id\": 42\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/client/client-custom/{client_id}")
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 \"custom_pricing\": {\n \"enabled\": true,\n \"frequency\": 0,\n \"amount\": 299,\n \"start_date\": \"2026-11-01\"\n },\n \"client_id\": 42\n}"
response = http.request(request)
puts response.read_body{
"message": "Custom pricing configuration saved. No payment was recorded.",
"client": {
"id": 207,
"organization": "Gratona Demo Org",
"website": "https://demo.gratona.com",
"email": "hello@demo.gratona.com",
"stripe_connect_id": "acct_1OqXXXXX",
"previous_stripe_connect_id": null,
"completed_stripe_onboarding": true,
"date_format": "Y-m-d",
"timezone": "America/Chicago",
"custom": {},
"frequency": {},
"custom_start_date": null,
"custom_amount": null,
"created_at": "2024-06-01T12:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Path Parameters
Client id in the current organization.
Body
Validated request fields for this operation.
Response
Operation result.
"Custom pricing configuration saved. No payment was recorded."
A Gratona client — the tenant of the multi-tenant system. Owns donors, entities, programs, users, and integrations. The client_id on every other resource scopes data to this row. Stripe Connect onboarding state, account-level settings, and the client's display name all live here.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.gratona.com/v1/client/client-custom/{client_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"custom_pricing": {
"enabled": true,
"frequency": 0,
"amount": 299,
"start_date": "2026-11-01"
},
"client_id": 42
}
'import requests
url = "https://api.gratona.com/v1/client/client-custom/{client_id}"
payload = {
"custom_pricing": {
"enabled": True,
"frequency": 0,
"amount": 299,
"start_date": "2026-11-01"
},
"client_id": 42
}
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({
custom_pricing: {enabled: true, frequency: 0, amount: 299, start_date: '2026-11-01'},
client_id: 42
})
};
fetch('https://api.gratona.com/v1/client/client-custom/{client_id}', 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://api.gratona.com/v1/client/client-custom/{client_id}",
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([
'custom_pricing' => [
'enabled' => true,
'frequency' => 0,
'amount' => 299,
'start_date' => '2026-11-01'
],
'client_id' => 42
]),
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://api.gratona.com/v1/client/client-custom/{client_id}"
payload := strings.NewReader("{\n \"custom_pricing\": {\n \"enabled\": true,\n \"frequency\": 0,\n \"amount\": 299,\n \"start_date\": \"2026-11-01\"\n },\n \"client_id\": 42\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://api.gratona.com/v1/client/client-custom/{client_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"custom_pricing\": {\n \"enabled\": true,\n \"frequency\": 0,\n \"amount\": 299,\n \"start_date\": \"2026-11-01\"\n },\n \"client_id\": 42\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/client/client-custom/{client_id}")
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 \"custom_pricing\": {\n \"enabled\": true,\n \"frequency\": 0,\n \"amount\": 299,\n \"start_date\": \"2026-11-01\"\n },\n \"client_id\": 42\n}"
response = http.request(request)
puts response.read_body{
"message": "Custom pricing configuration saved. No payment was recorded.",
"client": {
"id": 207,
"organization": "Gratona Demo Org",
"website": "https://demo.gratona.com",
"email": "hello@demo.gratona.com",
"stripe_connect_id": "acct_1OqXXXXX",
"previous_stripe_connect_id": null,
"completed_stripe_onboarding": true,
"date_format": "Y-m-d",
"timezone": "America/Chicago",
"custom": {},
"frequency": {},
"custom_start_date": null,
"custom_amount": null,
"created_at": "2024-06-01T12:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}