Skip to content

Instance settings

A stored instance setting, such as the app name, ToS URL, privacy policy URL or logo, takes precedence over its environment variable while the instance runs. All endpoints require the settings:manage permission.

const TOKEN = "hv_..."; // your API key
const headers = { Authorization: `Bearer ${TOKEN}` };
GET /admin/settings
const response = await fetch("http://127.0.0.1:3000/admin/settings", {
headers,
});
const data = await response.json();

Response: 200 OK

[
{ "key": "app_name", "value": "My HappyView", "source": "database" }
]

Stored values come first, sorted by key. They include every stored row, such as the logo_data and logo_content_type rows the logo upload writes. They are followed by values from the environment or happyview.toml for known keys with no stored value; a key with neither appears nowhere, even when it has a default. source is database, env or project.

KeyEnv varDefaultDescription
app_nameAPP_NAME---Application name shown in sidebar and OAuth consent screen
client_uriCLIENT_URI---Public URL for this instance, linked from OAuth consent screen
logo_uriLOGO_URI---External URL to a logo image
tos_uriTOS_URI---Link to terms of service
policy_uriPOLICY_URI---Link to privacy policy
backfill_concurrent_pdsBACKFILL_CONCURRENT_PDS10How many PDS servers to fetch from simultaneously during backfill
backfill_concurrent_dids_per_pdsBACKFILL_CONCURRENT_DIDS_PER_PDS3How many accounts to fetch concurrently from each PDS
backfill_concurrent_resolutionBACKFILL_CONCURRENT_RESOLUTION100How many DID document lookups to run in parallel during PDS resolution
backfill_retention_daysBACKFILL_RETENTION_DAYS28Days to keep per-account detail from completed backfill jobs. 0 = keep indefinitely
verbose_event_loggingVERBOSE_EVENT_LOGGINGfalseLog every record index, record skip, and successful script run (record, label, and XRPC) to the event log. "true" in any case turns it on, and a change takes up to 30 seconds to apply. High write volume, so recommended only for debugging
feature.spaces_enabledFEATURE_SPACES_ENABLED---Enables the experimental Permissioned Spaces API. When "true" (in any case), space endpoints are available. When absent or any other value, space endpoints return 404 FeatureDisabled
feature.spaces_pds_migration------When "true" (in any case), a user signing in with a space: scope granted gets a job enqueued to move the space repos HappyView keeps for them to their PDS
event_log_retention_daysEVENT_LOG_RETENTION_DAYS30Days to keep event log entries and job logs. 0 = keep indefinitely
script_instruction_limitSCRIPT_INSTRUCTION_LIMIT1000000Instruction budget for a script run. PUT refuses a value outside 1000 to 1000000000 with 400 Bad Request
script_wall_clock_secondsSCRIPT_WALL_CLOCK_SECONDS10Wall-clock limit for a request’s script run, in seconds. PUT refuses a value outside 1 to 300 with 400 Bad Request
script_metrics_enabledSCRIPT_METRICS_ENABLEDtrueRecord per-script run metrics for /admin/metrics. PUT refuses anything but "true" or "false" with 400 Bad Request
PUT /admin/settings/{key}
const response = await fetch("http://127.0.0.1:3000/admin/settings/app_name", {
method: "PUT",
headers: {
...headers,
"Content-Type": "application/json",
},
body: JSON.stringify({ value: "My HappyView" }),
});

The body is { "value": "..." }. The value is always a string, so send "true", not true. Any key is accepted; the table above lists the keys HappyView reads. logo, xrpc-proxy and telemetry are routes of their own, so PUT /admin/settings/telemetry reaches the telemetry endpoint, not this one.

Response: 204 No Content. 400 Bad Request when a script limit is out of range or script_metrics_enabled isn’t "true" or "false". A telemetry.* key returns 409 Conflict where a hosting platform manages telemetry.

DELETE /admin/settings/{key}

Removes the override; the corresponding environment variable or happyview.toml value (if any) takes effect again. Returns 404 Not Found if no value is stored for that key, and 409 Conflict for a telemetry.* key where a hosting platform manages telemetry.

Response: 204 No Content

GET /admin/settings/db-info

Returns database backend, connection pool sizes, and whether an instance restart is recommended to resize the backfill pool for current concurrency settings.

const response = await fetch("http://127.0.0.1:3000/admin/settings/db-info", {
headers,
});
const data = await response.json();

Response: 200 OK

{
"backend": "sqlite",
"server_max_connections": null,
"main_pool_size": 32,
"backfill_pool_size": 16,
"restart_recommended": false
}
FieldTypeDescription
backendstring"sqlite" or "postgres"
server_max_connectionsnumber | nullPostgres max_connections setting. null for SQLite
main_pool_sizenumberCurrent main connection pool size
backfill_pool_sizenumberCurrent backfill connection pool size
restart_recommendedbooleantrue if concurrency settings have changed and a restart would resize the pool
PUT /admin/settings/logo
DELETE /admin/settings/logo

PUT takes a multipart/form-data body whose first part is the image, and stores it as the instance logo. The logo is served publicly at GET /settings/logo, and is used in place of logo_uri while it is stored. The part’s content type must be image/* and it must be at most 5 MB, otherwise the request is refused with 400 Bad Request. DELETE removes the stored logo.

Response: 204 No Content for both.