curl --request POST \
--url https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"approval": {
"challengeIdentifier": "{{challengeIdentifier}}",
"firstFactor": {
"kind": "Fido2",
"credentialAssertion": {
"credId": "{{passkeyCredentialId}}",
"clientData": "{{passkeyClientData}}",
"signature": "{{passkeySignature}}",
"authenticatorData": "{{passkeyAuthenticatorData}}"
}
}
}
}
'import requests
url = "https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation"
payload = { "approval": {
"challengeIdentifier": "{{challengeIdentifier}}",
"firstFactor": {
"kind": "Fido2",
"credentialAssertion": {
"credId": "{{passkeyCredentialId}}",
"clientData": "{{passkeyClientData}}",
"signature": "{{passkeySignature}}",
"authenticatorData": "{{passkeyAuthenticatorData}}"
}
}
} }
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({
approval: {
challengeIdentifier: '{{challengeIdentifier}}',
firstFactor: {
kind: 'Fido2',
credentialAssertion: {
credId: '{{passkeyCredentialId}}',
clientData: '{{passkeyClientData}}',
signature: '{{passkeySignature}}',
authenticatorData: '{{passkeyAuthenticatorData}}'
}
}
}
})
};
fetch('https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation', 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://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation",
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([
'approval' => [
'challengeIdentifier' => '{{challengeIdentifier}}',
'firstFactor' => [
'kind' => 'Fido2',
'credentialAssertion' => [
'credId' => '{{passkeyCredentialId}}',
'clientData' => '{{passkeyClientData}}',
'signature' => '{{passkeySignature}}',
'authenticatorData' => '{{passkeyAuthenticatorData}}'
]
]
]
]),
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://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation"
payload := strings.NewReader("{\n \"approval\": {\n \"challengeIdentifier\": \"{{challengeIdentifier}}\",\n \"firstFactor\": {\n \"kind\": \"Fido2\",\n \"credentialAssertion\": {\n \"credId\": \"{{passkeyCredentialId}}\",\n \"clientData\": \"{{passkeyClientData}}\",\n \"signature\": \"{{passkeySignature}}\",\n \"authenticatorData\": \"{{passkeyAuthenticatorData}}\"\n }\n }\n }\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://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"approval\": {\n \"challengeIdentifier\": \"{{challengeIdentifier}}\",\n \"firstFactor\": {\n \"kind\": \"Fido2\",\n \"credentialAssertion\": {\n \"credId\": \"{{passkeyCredentialId}}\",\n \"clientData\": \"{{passkeyClientData}}\",\n \"signature\": \"{{passkeySignature}}\",\n \"authenticatorData\": \"{{passkeyAuthenticatorData}}\"\n }\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation")
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 \"approval\": {\n \"challengeIdentifier\": \"{{challengeIdentifier}}\",\n \"firstFactor\": {\n \"kind\": \"Fido2\",\n \"credentialAssertion\": {\n \"credId\": \"{{passkeyCredentialId}}\",\n \"clientData\": \"{{passkeyClientData}}\",\n \"signature\": \"{{passkeySignature}}\",\n \"authenticatorData\": \"{{passkeyAuthenticatorData}}\"\n }\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"state": "active",
"challenge": {
"challenge": "<string>",
"challengeIdentifier": "<string>",
"allowCredentials": {
"key": [
{
"type": "public-key",
"id": "<string>"
}
],
"webauthn": [
{
"type": "public-key",
"id": "<string>"
}
]
},
"userVerification": "required"
},
"failure": {
"reason": "approval_required"
}
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}Turn on automatic deposits
Turns automatic deposits on with one loop of owner commands, one challenge each: the HoldingDepositDelegation create (unless one is active), the archive of every other live delegation of the owner (a superseded factory or terms), the account’s USDCx TransferPreapproval where a bridge serves the environment and it is missing, and the switch of the owner’s one xReserve BridgeUserAgreement to preApproval true while the environment’s deposits.auto_move flag is on and the agreement still has it false (with it, Digital Asset’s bridge mints each deposit into the owner’s own Party with no click). That is at most four owner commands: the archive of a superseded delegation, the delegation, the USDCx pre-approval and the bridge pre-approval. The delegation lets the operator move USDCx already in the owner’s own Party into this same account, up to 500,000 per deposit, for 365 days from signing, through the transfer factory the token registry answers at signing. The terms come from the deployment manifest and the registry, never from the request, and the signer refuses a prepared transaction that differs in any of them. The delegation is approved with the owner’s passkey (Fido2) only; an approval of it by the account setup key is refused with HTTP 400 invalid_request. The passkey approves the first command of the turn on: the delegation, or, when the delegation is already active, the first remaining command. That passkey approval authorizes the account setup key to approve the remaining commands of the same turn on, each once, for five minutes. A setup key approval the server does not accept answers HTTP 400 invalid_request with setupKeyRefusal setup_key_refused: the client drops that key and approves with the passkey instead. Turning on therefore asks for one passkey prompt; it asks for two only when the browser holds no live setup key, because creating one takes a passkey approval of its own. The first call, with no approval, answers the first challenge; each call with the approval of that challenge signs it and answers the next challenge, or the final state. A stop names a closed failure.reason. With nothing to sign it answers active. Party setup must be active first. An account whose key Edel holds, or an environment that offers no delegation, answers HTTP 400 operation_not_available. Only the owner’s passkey session can call it. With feature flag party_setup off, this registered route answers HTTP 503 operation_not_available and names the flag in featureFlag.
Method and path: POST /v1/accounts//deposit-delegation
Authentication: DFNS trader bearer required.
Request schema: DepositDelegationRequest.
Response schema: DepositDelegationResponse.
Error envelope: ExternalRestError (external-rest-error/v1).
curl --request POST \
--url https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"approval": {
"challengeIdentifier": "{{challengeIdentifier}}",
"firstFactor": {
"kind": "Fido2",
"credentialAssertion": {
"credId": "{{passkeyCredentialId}}",
"clientData": "{{passkeyClientData}}",
"signature": "{{passkeySignature}}",
"authenticatorData": "{{passkeyAuthenticatorData}}"
}
}
}
}
'import requests
url = "https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation"
payload = { "approval": {
"challengeIdentifier": "{{challengeIdentifier}}",
"firstFactor": {
"kind": "Fido2",
"credentialAssertion": {
"credId": "{{passkeyCredentialId}}",
"clientData": "{{passkeyClientData}}",
"signature": "{{passkeySignature}}",
"authenticatorData": "{{passkeyAuthenticatorData}}"
}
}
} }
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({
approval: {
challengeIdentifier: '{{challengeIdentifier}}',
firstFactor: {
kind: 'Fido2',
credentialAssertion: {
credId: '{{passkeyCredentialId}}',
clientData: '{{passkeyClientData}}',
signature: '{{passkeySignature}}',
authenticatorData: '{{passkeyAuthenticatorData}}'
}
}
}
})
};
fetch('https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation', 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://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation",
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([
'approval' => [
'challengeIdentifier' => '{{challengeIdentifier}}',
'firstFactor' => [
'kind' => 'Fido2',
'credentialAssertion' => [
'credId' => '{{passkeyCredentialId}}',
'clientData' => '{{passkeyClientData}}',
'signature' => '{{passkeySignature}}',
'authenticatorData' => '{{passkeyAuthenticatorData}}'
]
]
]
]),
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://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation"
payload := strings.NewReader("{\n \"approval\": {\n \"challengeIdentifier\": \"{{challengeIdentifier}}\",\n \"firstFactor\": {\n \"kind\": \"Fido2\",\n \"credentialAssertion\": {\n \"credId\": \"{{passkeyCredentialId}}\",\n \"clientData\": \"{{passkeyClientData}}\",\n \"signature\": \"{{passkeySignature}}\",\n \"authenticatorData\": \"{{passkeyAuthenticatorData}}\"\n }\n }\n }\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://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"approval\": {\n \"challengeIdentifier\": \"{{challengeIdentifier}}\",\n \"firstFactor\": {\n \"kind\": \"Fido2\",\n \"credentialAssertion\": {\n \"credId\": \"{{passkeyCredentialId}}\",\n \"clientData\": \"{{passkeyClientData}}\",\n \"signature\": \"{{passkeySignature}}\",\n \"authenticatorData\": \"{{passkeyAuthenticatorData}}\"\n }\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://testnet.edel-api.xyz/v1/accounts/{accountId}/deposit-delegation")
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 \"approval\": {\n \"challengeIdentifier\": \"{{challengeIdentifier}}\",\n \"firstFactor\": {\n \"kind\": \"Fido2\",\n \"credentialAssertion\": {\n \"credId\": \"{{passkeyCredentialId}}\",\n \"clientData\": \"{{passkeyClientData}}\",\n \"signature\": \"{{passkeySignature}}\",\n \"authenticatorData\": \"{{passkeyAuthenticatorData}}\"\n }\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"state": "active",
"challenge": {
"challenge": "<string>",
"challengeIdentifier": "<string>",
"allowCredentials": {
"key": [
{
"type": "public-key",
"id": "<string>"
}
],
"webauthn": [
{
"type": "public-key",
"id": "<string>"
}
]
},
"userVerification": "required"
},
"failure": {
"reason": "approval_required"
}
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"featureFlag": "<string>",
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found",
"positionSnapshotRefusal": "position_projection_behind_live",
"setupKeyRefusal": "setup_key_refused"
}Authorizations
The authorization field takes the session bearer returned by sign-in, or an API key where the route allows keys. Paste the token itself into the authorization field. When invitation-only access is enabled, private operations require the account's sign-in email to be invited. Sign-in can complete without an invitation, but private HTTP, MCP and FIX operations refuse with access_not_allowlisted (HTTP 403): "Private access is limited to invited accounts. Contact support to request access." Public market data remains available. Invitation changes apply to the next private operation, including existing FIX sessions. Do not retry until support confirms access.
Path Parameters
1Body
Show child attributes
Show child attributes