Activate a wallet from its on-chain allowances
curl --request POST \
--url https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification', 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.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "VERIFYING_ALLOWANCE",
"verificationExpiresAt": "2026-08-20T15:04:05Z",
"assets": [
{
"supportedAssetId": "5d4c5b99-2ce8-40a1-bc1d-173dd400fa89",
"asset": "USDC",
"contractAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"allowanceSufficient": true,
"permitStatus": "CONFIRMED"
},
{
"supportedAssetId": "352fa5ad-ca00-4701-905f-744b867f6d5d",
"asset": "EURC",
"contractAddress": "0x808456652fdb597867f38412077a9182bf77359f",
"allowanceSufficient": false,
"permitStatus": "PENDING"
}
]
}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "unauthenticated",
"message": "Please authenticate to perform this action."
}
]
}{
"success": false,
"errors": [
{
"code": "forbidden",
"message": "You do not have permission to access this resource."
}
]
}{
"success": false,
"errors": [
{
"code": "account-not-found",
"message": "The requested resource was not found."
}
]
}{
"success": false,
"errors": [
{
"code": "internal-error",
"message": "An unexpected error occurred. Please try again later."
}
]
}Allowances
Verify wallet allowances
Activate a self-custody wallet from the allowances it has already granted on-chain.
POST
/
accounts
/
{accountId}
/
wallets
/
{walletId}
/
allowance-verification
Activate a wallet from its on-chain allowances
curl --request POST \
--url https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification', 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.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.venlyfinance.com/v1/accounts/{accountId}/wallets/{walletId}/allowance-verification")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"walletId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "VERIFYING_ALLOWANCE",
"verificationExpiresAt": "2026-08-20T15:04:05Z",
"assets": [
{
"supportedAssetId": "5d4c5b99-2ce8-40a1-bc1d-173dd400fa89",
"asset": "USDC",
"contractAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"allowanceSufficient": true,
"permitStatus": "CONFIRMED"
},
{
"supportedAssetId": "352fa5ad-ca00-4701-905f-744b867f6d5d",
"asset": "EURC",
"contractAddress": "0x808456652fdb597867f38412077a9182bf77359f",
"allowanceSufficient": false,
"permitStatus": "PENDING"
}
]
}
}{
"success": false,
"errors": [
{
"code": "invalid-request",
"message": "The request contains invalid parameters."
}
],
"result": {}
}{
"success": false,
"errors": [
{
"code": "unauthenticated",
"message": "Please authenticate to perform this action."
}
]
}{
"success": false,
"errors": [
{
"code": "forbidden",
"message": "You do not have permission to access this resource."
}
]
}{
"success": false,
"errors": [
{
"code": "account-not-found",
"message": "The requested resource was not found."
}
]
}{
"success": false,
"errors": [
{
"code": "internal-error",
"message": "An unexpected error occurred. Please try again later."
}
]
}Requires scope:
Read
manage:accounts — see Required scopes.
Activates a self-custody account wallet by reading the allowances it has already granted on-chain, instead of going through the permit flow.
This is the route for a smart-contract wallet — a Safe, for example. A contract wallet is controlled by its owners rather than a single key, so it cannot produce the one signature a permit needs. It grants the same permission with a plain approve(spender, amount) transaction instead.
The allowance is the consent: only the wallet’s controller could have granted it. So this endpoint reads public chain state and takes no request body and no proof.
What happens when you call it
1
Allowances are read synchronously
Every asset covered by a sufficient allowance is marked confirmed.
2
All assets covered → ACTIVE
The wallet is usable immediately.
3
Some assets missing → VERIFYING_ALLOWANCE
You get a
verificationExpiresAt. Venly keeps re-checking until then, so granting the remaining allowances is enough — you don’t have to call again.VERIFYING_ALLOWANCE is a waiting room, not a usable state. Every check that requires an active wallet treats it exactly like PENDING, so don’t offer the wallet to an end-user until it reads ACTIVE.If the window closes with assets still uncovered, the wallet falls back to PENDING and you start again.assets[] to see exactly which allowances are still missing — allowanceSufficient is per asset.
Both activation routes end in the same place: a wallet is ACTIVE once every supported asset is covered. See Permits and allowances.
Errors
The codes this endpoint can return, in addition to the standard errors. Branch oncode, never the message.
| HTTP | code | When |
|---|---|---|
400 | wallet-not-verifiable | the wallet cannot enter verification: it is already ACTIVE, or it is FROZEN/CLOSED |
400 | invalid-request | the wallet is Venly-managed, so it activates through the permit flow instead |
Authorizations
OAuth2 client credentials flow. Token endpoints:
Path Parameters
Unique account identifier
Unique wallet identifier
Was this page helpful?

