curl --request PUT \
--url https://api.vitawallet.io/api/businesses/webhooks \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'x-date: <api-key>' \
--header 'x-login: <api-key>' \
--header 'x-trans-key: <api-key>' \
--data '
{
"webhook_url": "https://myserver.com",
"categories": [
"deposit"
]
}
'import requests
url = "https://api.vitawallet.io/api/businesses/webhooks"
payload = {
"webhook_url": "https://myserver.com",
"categories": ["deposit"]
}
headers = {
"x-login": "<api-key>",
"x-trans-key": "<api-key>",
"x-date": "<api-key>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'x-login': '<api-key>',
'x-trans-key': '<api-key>',
'x-date': '<api-key>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({webhook_url: 'https://myserver.com', categories: ['deposit']})
};
fetch('https://api.vitawallet.io/api/businesses/webhooks', 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.vitawallet.io/api/businesses/webhooks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'webhook_url' => 'https://myserver.com',
'categories' => [
'deposit'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"x-date: <api-key>",
"x-login: <api-key>",
"x-trans-key: <api-key>"
],
]);
$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://api.vitawallet.io/api/businesses/webhooks"
payload := strings.NewReader("{\n \"webhook_url\": \"https://myserver.com\",\n \"categories\": [\n \"deposit\"\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("x-login", "<api-key>")
req.Header.Add("x-trans-key", "<api-key>")
req.Header.Add("x-date", "<api-key>")
req.Header.Add("Authorization", "<api-key>")
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.put("https://api.vitawallet.io/api/businesses/webhooks")
.header("x-login", "<api-key>")
.header("x-trans-key", "<api-key>")
.header("x-date", "<api-key>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"webhook_url\": \"https://myserver.com\",\n \"categories\": [\n \"deposit\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vitawallet.io/api/businesses/webhooks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["x-login"] = '<api-key>'
request["x-trans-key"] = '<api-key>'
request["x-date"] = '<api-key>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"webhook_url\": \"https://myserver.com\",\n \"categories\": [\n \"deposit\"\n ]\n}"
response = http.request(request)
puts response.read_bodyUpdate Webhook Configuration
Updates the webhook configuration for your business, setting or replacing the destination URL and the list of subscribed categories.
Before Vita Accepts the New URL: Pre-Verification Ping
As soon as you submit a new webhook_url, Vita immediately sends an unsigned test request to that URL:
{"test":true,"timestamp":"..."}
Your server must respond with a 2xx or 3xx status code within 10 seconds, or the configuration update is rejected. This request carries no signature — if your server is built to reject unsigned requests (as recommended for regular webhooks), it will also reject this pre-verification ping and you will never be able to save a new URL. Make sure your endpoint accepts this specific unsigned probe, or temporarily relax validation while configuring.
Post-Update Test Webhook (Conditional)
After a successful update, Vita attempts to send a signed test webhook using the most recent transaction that matches your configured categories. This only happens if such a transaction exists:
-
If a matching transaction exists: the response message is
"Webhook configuration updated successfully. You will receive a test webhook in the next few minutes.", and the test webhook is sent shortly after. -
If no matching transaction exists (e.g., new business, or categories with no history): the response message is instead
"Webhook configuration updated successfully. However, no transaction was found matching the configured categories to send a test webhook. You will receive webhooks when new transactions occur matching the configured categories."— and no test webhook is sent at all.
Both outcomes save the configuration correctly; only the test-webhook behavior differs.
Request Body
| Field | Type | Description |
|---|---|---|
webhook_url | string (required) | HTTPS URL where webhook notifications will be sent. |
categories | string[] (Required (see note)) | List of transaction categories to subscribe to. Must contain valid categories returned by Get Webhook Configuration (available_categories). |
categoriesis documented as required, but the API currently accepts the request without it — and interprets a missingcategoriesfield as “unsubscribe from everything.” Until this is enforced API-side, always send the field explicitly with your full intended list to avoid silently losing all your subscriptions.
There is currently no way to remove your webhook configuration by sending
webhook_url: nullor an empty string. Both are rejected by the API with a422error ("URL is blank"), and the existing configuration is left unchanged. If you need to stop receiving webhooks, contact your integration contact — self-service removal is not available today.
Request Example
curl --location --request PUT 'https://api.vitawallet.io/api/businesses/webhooks' \
--header 'X-Login: {your_x_login}' \
--header 'X-Trans-Key: {your_x_trans_key}' \
--header 'X-Date: {current_iso8601_timestamp_with_timezone}' \
--header 'Authorization: {signature_calculated_per_the_Business_API_authentication_doc}' \
--header 'Content-Type: application/json' \
--data '{
"webhook_url": "https://myserver.com/webhook",
"categories": [
"transfer",
"deposit"
]
}'
Response Example
{
"message": "Webhook configuration updated successfully. You will receive a test webhook in the next few minutes.",
"webhook_url": "https://myserver.com/webhook",
"categories": [
"transfer",
"deposit"
]
}
Important Considerations
Use HTTPS The webhook URL must use HTTPS. HTTP URLs are not accepted for security reasons.
Your Server Must Handle Two Kinds of Incoming Test Traffic
-
The unsigned pre-verification ping described above, sent the moment you submit a new URL.
-
The signed post-update test webhook, sent only when a matching transaction exists.
Replace, Not Append
The categories array completely replaces the existing list. Always send the full list of categories you want active — and always include the field, since omitting it clears all subscriptions.
Removing the Webhook
Self-service removal via null/empty string is not currently supported. Contact your integration contact if you need your configuration removed.
curl --request PUT \
--url https://api.vitawallet.io/api/businesses/webhooks \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'x-date: <api-key>' \
--header 'x-login: <api-key>' \
--header 'x-trans-key: <api-key>' \
--data '
{
"webhook_url": "https://myserver.com",
"categories": [
"deposit"
]
}
'import requests
url = "https://api.vitawallet.io/api/businesses/webhooks"
payload = {
"webhook_url": "https://myserver.com",
"categories": ["deposit"]
}
headers = {
"x-login": "<api-key>",
"x-trans-key": "<api-key>",
"x-date": "<api-key>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'x-login': '<api-key>',
'x-trans-key': '<api-key>',
'x-date': '<api-key>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({webhook_url: 'https://myserver.com', categories: ['deposit']})
};
fetch('https://api.vitawallet.io/api/businesses/webhooks', 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.vitawallet.io/api/businesses/webhooks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'webhook_url' => 'https://myserver.com',
'categories' => [
'deposit'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"x-date: <api-key>",
"x-login: <api-key>",
"x-trans-key: <api-key>"
],
]);
$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://api.vitawallet.io/api/businesses/webhooks"
payload := strings.NewReader("{\n \"webhook_url\": \"https://myserver.com\",\n \"categories\": [\n \"deposit\"\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("x-login", "<api-key>")
req.Header.Add("x-trans-key", "<api-key>")
req.Header.Add("x-date", "<api-key>")
req.Header.Add("Authorization", "<api-key>")
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.put("https://api.vitawallet.io/api/businesses/webhooks")
.header("x-login", "<api-key>")
.header("x-trans-key", "<api-key>")
.header("x-date", "<api-key>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"webhook_url\": \"https://myserver.com\",\n \"categories\": [\n \"deposit\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vitawallet.io/api/businesses/webhooks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["x-login"] = '<api-key>'
request["x-trans-key"] = '<api-key>'
request["x-date"] = '<api-key>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"webhook_url\": \"https://myserver.com\",\n \"categories\": [\n \"deposit\"\n ]\n}"
response = http.request(request)
puts response.read_bodyAuthorizations
Business xLogin
Business xTransKey
ISO8601 datetime
V2-HMAC-SHA256 signature. Example: V2-HMAC-SHA256, Signature: <hash>
Body
The body is of type object.
Response
Successful response.