External Tooling Settings API
The external tooling settings API lets a service-authenticated integration preview proposed app or organization settings changes, show them to a human for review, and apply them only if the reviewed state is still current. It exposes two endpoints: POST /tooling/external/settings/preview and POST /tooling/external/settings/update.
Authentication and permissions
Both endpoints authenticate with a Bearer token in the Authorization header using an active tooling service credential for the environment you are calling. A missing, invalid, expired, or revoked token returns 401 unauthorized.
Each endpoint checks its own permission:
POST /tooling/external/settings/previewrequiressettings:readorsettings:write.POST /tooling/external/settings/updaterequiressettings:write.
A credential without the required permission returns 403 forbidden.
Preview then update workflow
Settings changes go through two calls. First, preview the proposed change to validate it and see the before and after values for each setting. A human reviews the result. Then apply the change with the update call, passing back the expected and expected_parent snapshots the preview returned.
Preview performs no writes and takes no locks. Update applies the whole batch in a single transaction, and only if the reviewed values are still current.
POST /tooling/external/settings/preview
Preview validates a proposed change or reset for an app or organization and returns the before and after values for each setting, plus the expected snapshots you pass to the update call. It never writes settings.
Request
Field | Type | Required | Description |
|---|---|---|---|
| string | yes |
|
| string (UUID) | yes | ID of the app or organization |
| object | no | Setting names mapped to their new values |
| array of strings | no | Setting names to reset to their inherited or default value |
A setting cannot appear in both changes and reset, and reset cannot contain duplicates. The preview request must not include expected or expected_parent; those belong to the update call.
Example request:
{
"kind": "organizations",
"entity_id": "your-entity-id",
"changes": {
"min_payout_amount": 25.00
}
}Response
The response includes the entity, one entry per changed or reset setting, and the expected snapshots for the update step.
Field | Type | Description |
|---|---|---|
| object | Object with |
| array | One entry per changed or reset setting |
| object | Current stored value for each changed or reset setting |
| object or null | Parent stored value for each reset setting, or |
Each entry in changes includes:
name— the setting nameaction—changefor a setting inchanges, orresetfor a setting inresetbefore— object with the current stored value and itseffectivevalueafter— object with the proposed stored value and itseffectivevalue
Example response:
{
"entity": {
"id": "your-entity-id",
"name": "My Organization"
},
"changes": [
{
"name": "min_payout_amount",
"action": "change",
"before": {
"min_payout_amount": 10.00,
"effective": 10.00
},
"after": {
"min_payout_amount": 25.00,
"effective": 25.00
}
}
],
"expected": {
"min_payout_amount": 10.00
},
"expected_parent": null
}POST /tooling/external/settings/update
Update applies a reviewed settings batch only if the settings are still current. It requires the expected snapshot from the preview call, and for apps the expected_parent snapshot as well.
Request
Field | Type | Required | Description |
|---|---|---|---|
| string | yes |
|
| string (UUID) | yes | ID of the app or organization |
| object | no | Setting names mapped to their new values |
| array of strings | no | Setting names to reset |
| object | yes | Current stored values from the preview response |
| object | apps only | Parent stored values for reset settings; required for apps, not allowed for organizations |
For kind: "apps", expected_parent is required. For kind: "organizations", it must not be included; including it returns 400 invalid_request.
Example request:
{
"kind": "apps",
"entity_id": "your-entity-id",
"reset": ["min_payout_amount"],
"expected": {
"min_payout_amount": 25.00
},
"expected_parent": {
"min_payout_amount": 15.00
}
}Response
A successful update returns success: true and the resulting override state for each changed or reset setting. The response reports stored overrides only, not effective inherited values.
{
"success": true,
"values": {
"min_payout_amount": {
"has_override": false,
"override": null
}
}
}Resets and app inheritance
Resetting a setting removes its stored override. For an app, an inheritable setting then resolves to the organization's current value, or to the setting's default if the organization has no stored value. App settings resolve in this order: the app's stored override, then the organization's value, then the setting's default.
Because an app reset can fall back to an organization value, app updates must include expected_parent. If the organization value changed after review, the update is rejected as stale so the inherited value cannot be applied against a parent that changed.
Error handling
HTTP | Error | Meaning |
|---|---|---|
401 |
| Missing, invalid, expired, or revoked token |
403 |
| Credential lacks the required permission |
404 |
| App or organization not found |
400 |
| Invalid request body or settings |
409 |
| A reviewed value changed; refresh and review again |
When a reviewed value changed since it was loaded, the update is rejected in full with 409 stale_settings and a message naming the setting, for example min_payout_amount changed since it was loaded. Refresh and review again. For an inherited app value, the message reads min_payout_amount inherited value changed since it was loaded. Refresh and review again. Run a fresh preview, review the new values, and retry the update.
Settings not available through this API
Approval and API-access settings (approved, api_access_approved) and PayPal credentials are not available through these endpoints. They remain handled by the existing internal tooling routes.