curl --request POST \
--url https://api.services.payward.com/v1/webhooks \
--header 'API-Key: <api-key>' \
--header 'API-Nonce: <api-key>' \
--header 'API-Sign: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://partner.example.com/hooks/quote",
"description": "primary delivery",
"events": [
"quote.executed",
"quote.cancelled"
]
}
'import requests
url = "https://api.services.payward.com/v1/webhooks"
payload = {
"url": "https://partner.example.com/hooks/quote",
"description": "primary delivery",
"events": ["quote.executed", "quote.cancelled"]
}
headers = {
"API-Key": "<api-key>",
"API-Sign": "<api-key>",
"API-Nonce": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'API-Key': '<api-key>',
'API-Sign': '<api-key>',
'API-Nonce': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://partner.example.com/hooks/quote',
description: 'primary delivery',
events: ['quote.executed', 'quote.cancelled']
})
};
fetch('https://api.services.payward.com/v1/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.services.payward.com/v1/webhooks",
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([
'url' => 'https://partner.example.com/hooks/quote',
'description' => 'primary delivery',
'events' => [
'quote.executed',
'quote.cancelled'
]
]),
CURLOPT_HTTPHEADER => [
"API-Key: <api-key>",
"API-Nonce: <api-key>",
"API-Sign: <api-key>",
"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://api.services.payward.com/v1/webhooks"
payload := strings.NewReader("{\n \"url\": \"https://partner.example.com/hooks/quote\",\n \"description\": \"primary delivery\",\n \"events\": [\n \"quote.executed\",\n \"quote.cancelled\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("API-Key", "<api-key>")
req.Header.Add("API-Sign", "<api-key>")
req.Header.Add("API-Nonce", "<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.post("https://api.services.payward.com/v1/webhooks")
.header("API-Key", "<api-key>")
.header("API-Sign", "<api-key>")
.header("API-Nonce", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://partner.example.com/hooks/quote\",\n \"description\": \"primary delivery\",\n \"events\": [\n \"quote.executed\",\n \"quote.cancelled\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.services.payward.com/v1/webhooks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["API-Key"] = '<api-key>'
request["API-Sign"] = '<api-key>'
request["API-Nonce"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://partner.example.com/hooks/quote\",\n \"description\": \"primary delivery\",\n \"events\": [\n \"quote.executed\",\n \"quote.cancelled\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "ep_2YuTbBzs6F8XUjWk7p7uA9KNdL5",
"url": "https://partner.example.com/hooks/quote",
"description": "primary delivery",
"disabled": false,
"created_at": "2026-05-25T11:30:00Z",
"updated_at": "2026-05-25T11:30:00Z",
"signing_secret": "whsec_7nM1q4bV2jKbMZhYa3sAehO9W8r7QZD2",
"events": [
"quote.executed",
"quote.cancelled"
]
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 400,
"code": "bad_request",
"causes": [
{
"field": "page_size",
"message": "must be between 1 and 25"
}
]
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 401,
"code": "unauthenticated"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 403,
"code": "forbidden"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 429,
"code": "resource_exhausted"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 500,
"code": "internal"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 503,
"code": "unavailable"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 504,
"code": "deadline_exceeded"
}
}Create webhook
Registers a new webhook destination for the specified account.
The response carries the signing secret in plaintext. Partners must store it and use it to verify the signature on inbound webhook deliveries. The secret is shown only here at creation time; if it is later lost or compromised, mint a replacement with RotateWebhookSecret (which returns the new secret, also only once).
curl --request POST \
--url https://api.services.payward.com/v1/webhooks \
--header 'API-Key: <api-key>' \
--header 'API-Nonce: <api-key>' \
--header 'API-Sign: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://partner.example.com/hooks/quote",
"description": "primary delivery",
"events": [
"quote.executed",
"quote.cancelled"
]
}
'import requests
url = "https://api.services.payward.com/v1/webhooks"
payload = {
"url": "https://partner.example.com/hooks/quote",
"description": "primary delivery",
"events": ["quote.executed", "quote.cancelled"]
}
headers = {
"API-Key": "<api-key>",
"API-Sign": "<api-key>",
"API-Nonce": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'API-Key': '<api-key>',
'API-Sign': '<api-key>',
'API-Nonce': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://partner.example.com/hooks/quote',
description: 'primary delivery',
events: ['quote.executed', 'quote.cancelled']
})
};
fetch('https://api.services.payward.com/v1/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.services.payward.com/v1/webhooks",
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([
'url' => 'https://partner.example.com/hooks/quote',
'description' => 'primary delivery',
'events' => [
'quote.executed',
'quote.cancelled'
]
]),
CURLOPT_HTTPHEADER => [
"API-Key: <api-key>",
"API-Nonce: <api-key>",
"API-Sign: <api-key>",
"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://api.services.payward.com/v1/webhooks"
payload := strings.NewReader("{\n \"url\": \"https://partner.example.com/hooks/quote\",\n \"description\": \"primary delivery\",\n \"events\": [\n \"quote.executed\",\n \"quote.cancelled\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("API-Key", "<api-key>")
req.Header.Add("API-Sign", "<api-key>")
req.Header.Add("API-Nonce", "<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.post("https://api.services.payward.com/v1/webhooks")
.header("API-Key", "<api-key>")
.header("API-Sign", "<api-key>")
.header("API-Nonce", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://partner.example.com/hooks/quote\",\n \"description\": \"primary delivery\",\n \"events\": [\n \"quote.executed\",\n \"quote.cancelled\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.services.payward.com/v1/webhooks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["API-Key"] = '<api-key>'
request["API-Sign"] = '<api-key>'
request["API-Nonce"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://partner.example.com/hooks/quote\",\n \"description\": \"primary delivery\",\n \"events\": [\n \"quote.executed\",\n \"quote.cancelled\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "ep_2YuTbBzs6F8XUjWk7p7uA9KNdL5",
"url": "https://partner.example.com/hooks/quote",
"description": "primary delivery",
"disabled": false,
"created_at": "2026-05-25T11:30:00Z",
"updated_at": "2026-05-25T11:30:00Z",
"signing_secret": "whsec_7nM1q4bV2jKbMZhYa3sAehO9W8r7QZD2",
"events": [
"quote.executed",
"quote.cancelled"
]
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 400,
"code": "bad_request",
"causes": [
{
"field": "page_size",
"message": "must be between 1 and 25"
}
]
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 401,
"code": "unauthenticated"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 403,
"code": "forbidden"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 429,
"code": "resource_exhausted"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 500,
"code": "internal"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 503,
"code": "unavailable"
}
}{
"error": {
"type": "webhooks_error",
"instance": "req_01H00000000000000000000000",
"status": 504,
"code": "deadline_exceeded"
}
}Authorizations
Your public API key. Identifies the partner making the request.
HMAC signature over the request, computed with your private key.
Monotonically increasing nonce included in the request signature.
Body
Request to register a new webhook destination.
The owning tenant is derived from the authenticated caller. There is no account identifier in the request.
HTTPS destination URL. Must be reachable from the webhooks service and serve a valid TLS certificate.
8 - 2048Events the webhook should be subscribed to. Required and must be non-empty: partners must opt in explicitly to avoid silent fan-out when new event types are added.
1 - 100 elementsEvent type supported by the webhooks API.
quote.executed, quote.cancelled, quote.execution_failed, user.closed, user.disabled, conversion.deposit_completed, conversion.deposit_failed, conversion.deposit_held, conversion.withdrawal_completed, conversion.withdrawal_failed, conversion.quote_execution_failed, conversion.travel_rule_blocked, transaction.swap, transaction.price_trigger_swap, transaction.earn_reward, transaction.deposit, transaction.withdrawal, transaction.transfer, conversion.quote_executed, funds.deposit_received, funds.deposit_held, funds.deposit_credited, funds.deposit_returned, funds.deposit_failed, verification.requirements_updated, verification.updated, price_trigger_swap.executed, price_trigger_swap.execution_failed, price_trigger_swap.cancelled, price_trigger_swap.created, price_trigger_swap.failed, funds.withdrawal_held, funds.withdrawal_complete, funds.withdrawal_failed, recurring_swap.created, recurring_swap.executed, recurring_swap.execution_failed, recurring_swap.cancelled, recurring_swap.failed, recurring_swap.paused, recurring_swap.resumed, transaction.recurring_swap Optional free-form label, shown in the operator portal. Max 500 chars.
500Create the webhook in a disabled state. Omit (or pass false) to start delivering immediately; pass true to register the endpoint without delivering any events until it is re-enabled via UpdateWebhook.
Response
Successful response
Response from CreateWebhook.
The signing secret is returned in plaintext exactly once. Partners must persist it before discarding the response; it cannot be re-read later.
Data envelope returned exactly once after a successful CreateWebhook. Mirrors the webhook representation field-for-field and adds the one-time signing secret as a peer field.
Show child attributes
Show child attributes