Skip to main content

Upsert Custody Provider

Creates or updates a custody provider's configuration. Saving never changes which provider is active: a new provider is created inactive, and an existing one keeps its is_active. Use Activate Custody Provider to switch.

Credentials are nullable on purpose. You cannot read username, password or api_key back, so a save that leaves them out must not erase them:

  • omitted or null keeps the stored value;
  • "" clears it;
  • any other string replaces it.

webhook.auth_type and webhook.username work the same way (omitted or null keeps). The webhook secret is not writable here: it is generated by Regenerate Webhook Secret and stored only as a hash. host, port and timeout are always written as sent.

Rules a save is checked against:

  • Stored secrets stay with their endpoint. Moving the provider to another host or port while a stored password, api_key or client certificate would be carried over is refused with 10015, naming each field to send again (password, api_key, client_key). A client certificate cannot be sent through this API, so a provider that has one cannot be moved to another endpoint here.
  • Plain http only inside the cluster. This API cannot turn TLS on; a provider keeps the TLS setting it already has, and a new one starts with TLS off. With TLS off, host must be an in-cluster host listed for the environment, otherwise the save is refused with 10015 naming host.
  • A basic webhook pair is kept whole. With webhook.auth_type basic and a secret already generated, webhook.username cannot be cleared (or left empty when switching to basic).

Platform owner only. The caller's node must be the platform root node; any other caller is refused with 403 / 10005.

Required permission: custodial-wallet:update

Request​

PUT /v2/admin/custodial-wallets/{provider}

Parameters​

NameTypeInDescription
providerstringpathRequired. Provider key: rudiq or taurus

Headers​

NameDescription
AuthorizationRequired. Bearer <access_token>
Content-TypeRequired. application/json

Body​

FieldTypeRequiredDescription
hoststringYesHost name of the provider's API, without scheme, port or path
portintegerNoPort of the provider's API, 0 or greater
timeoutintegerNoRequest timeout in seconds, 0 or greater
usernamestring | nullNoUsername the platform presents to custody. null keeps, "" clears
passwordstring | nullNoPassword the platform presents to custody. null keeps, "" clears
api_keystring | nullNoAPI key the platform presents to custody. null keeps, "" clears
webhookobject | nullNoInbound webhook settings. Omitted or null keeps both
webhook.auth_typestring | nullNobasic or token. null keeps the stored value (basic for a new provider)
webhook.usernamestring | nullNoUsername custody sends with basic auth. null keeps

Example​

curl --request PUT \
--url '{{baseUrl}}/v2/admin/custodial-wallets/rudiq' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"host": "custody-gateway.custody.svc.cluster.local",
"port": 8080,
"timeout": 30,
"username": null,
"password": null,
"api_key": "<custody_api_key>",
"webhook": {
"auth_type": "basic",
"username": "apex-custody"
}
}'

Response​

200 OK with the saved provider, masked as on List Custody Providers.

{
"provider": "rudiq",
"host": "custody-gateway.custody.svc.cluster.local",
"port": 8080,
"timeout": 30,
"is_active": false,
"effective_active": false,
"username_set": false,
"password_set": false,
"api_key_set": true,
"api_key_last4": "7c1e",
"configured": true,
"webhook": {
"auth_type": "basic",
"path": "/v2/webhooks/custodial",
"url": "https://integration.example.com/v2/webhooks/custodial",
"username": "apex-custody",
"secret_set": false
},
"created_at": "2026-11-09T11:02:37.640Z",
"updated_at": "2026-11-09T11:02:37.640Z"
}

Errors​

StatusCodeDescription
40010015Validation failed (host missing, negative port or timeout), unsupported provider key, unsupported webhook.auth_type, a basic webhook secret left without its username, or (with details) a stored secret that would move to a new endpoint or a plain-http host outside the cluster
40310005The caller is not the platform owner (domain 2)

See Errors for the error format and common codes.