Add a notification endpoint
curl --request POST \
--url https://api.returnshelper.com/uat/user/api/Notification/Add \
--header 'Content-Type: application/json' \
--header 'x-rr-apikey: <api-key>' \
--header 'x-rr-apitoken: <api-key>' \
--data '
{
"endpoint": "https://acme.example/hooks/returnhelper"
}
'import requests
url = "https://api.returnshelper.com/uat/user/api/Notification/Add"
payload = { "endpoint": "https://acme.example/hooks/returnhelper" }
headers = {
"x-rr-apikey": "<api-key>",
"x-rr-apitoken": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-rr-apikey': '<api-key>',
'x-rr-apitoken': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({endpoint: 'https://acme.example/hooks/returnhelper'})
};
fetch('https://api.returnshelper.com/uat/user/api/Notification/Add', 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.returnshelper.com/uat/user/api/Notification/Add",
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([
'endpoint' => 'https://acme.example/hooks/returnhelper'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-rr-apikey: <api-key>",
"x-rr-apitoken: <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.returnshelper.com/uat/user/api/Notification/Add"
payload := strings.NewReader("{\n \"endpoint\": \"https://acme.example/hooks/returnhelper\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-rr-apikey", "<api-key>")
req.Header.Add("x-rr-apitoken", "<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.returnshelper.com/uat/user/api/Notification/Add")
.header("x-rr-apikey", "<api-key>")
.header("x-rr-apitoken", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"endpoint\": \"https://acme.example/hooks/returnhelper\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.returnshelper.com/uat/user/api/Notification/Add")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-rr-apikey"] = '<api-key>'
request["x-rr-apitoken"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"endpoint\": \"https://acme.example/hooks/returnhelper\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"apiNotificationId": 1234,
"endpoint": "https://acme.example/hooks/returnhelper"
}
}{
"correlationId": "<string>",
"meta": {
"status": 123,
"data": {},
"errorCode": "<string>",
"error": {}
}
}Notification
Add a notification endpoint
POST
/
api
/
Notification
/
Add
Add a notification endpoint
curl --request POST \
--url https://api.returnshelper.com/uat/user/api/Notification/Add \
--header 'Content-Type: application/json' \
--header 'x-rr-apikey: <api-key>' \
--header 'x-rr-apitoken: <api-key>' \
--data '
{
"endpoint": "https://acme.example/hooks/returnhelper"
}
'import requests
url = "https://api.returnshelper.com/uat/user/api/Notification/Add"
payload = { "endpoint": "https://acme.example/hooks/returnhelper" }
headers = {
"x-rr-apikey": "<api-key>",
"x-rr-apitoken": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-rr-apikey': '<api-key>',
'x-rr-apitoken': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({endpoint: 'https://acme.example/hooks/returnhelper'})
};
fetch('https://api.returnshelper.com/uat/user/api/Notification/Add', 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.returnshelper.com/uat/user/api/Notification/Add",
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([
'endpoint' => 'https://acme.example/hooks/returnhelper'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-rr-apikey: <api-key>",
"x-rr-apitoken: <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.returnshelper.com/uat/user/api/Notification/Add"
payload := strings.NewReader("{\n \"endpoint\": \"https://acme.example/hooks/returnhelper\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-rr-apikey", "<api-key>")
req.Header.Add("x-rr-apitoken", "<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.returnshelper.com/uat/user/api/Notification/Add")
.header("x-rr-apikey", "<api-key>")
.header("x-rr-apitoken", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"endpoint\": \"https://acme.example/hooks/returnhelper\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.returnshelper.com/uat/user/api/Notification/Add")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-rr-apikey"] = '<api-key>'
request["x-rr-apitoken"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"endpoint\": \"https://acme.example/hooks/returnhelper\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"apiNotificationId": 1234,
"endpoint": "https://acme.example/hooks/returnhelper"
}
}{
"correlationId": "<string>",
"meta": {
"status": 123,
"data": {},
"errorCode": "<string>",
"error": {}
}
}Registers an HTTPS endpoint to receive webhook notifications. Return Helper sends a verification request to the URL before storing it — registration succeeds only if your endpoint answers.
All of the above are checked before the verification request is sent, so a rejected request never reaches your server.
Endpoint requirements
| Rule | Detail |
|---|---|
| Scheme | https only. |
| Length | 255 characters or fewer, measured after normalization. |
| Reachability | Must be publicly reachable. Loopback, private-network and link-local addresses are rejected. |
| Uniqueness | The URL must not already be registered by your account. |
| Limit | Up to 5 endpoints per account. If your account is configured with a different limit, the error message states it. |
The endpoint receives every event
A registered endpoint receives all notification events for your account. There is no per-event subscription or filter on the Return Helper side. Filter on your side: read thecategory and action fields from the notification body and ignore the events you do not handle. Acknowledge every request with a 2xx status even when you ignore it — a non-2xx response counts as a failed delivery and repeated failures suspend delivery to your endpoint. See Retry Mechanism.
Get HTTP notification action types for users lists the action values you can expect.
Verification request
Before the endpoint is stored, Return Helper sends aPOST to the URL you supplied. It carries a fixed sample payload in the shape of a label generated notification and the complete set of notification headers, including a valid ReturnHelper-Signature — so your handler and your signature check can be exercised end to end before you go live.
Registration succeeds only if your endpoint returns a 2xx status within 30 seconds. Any other status, a timeout, a DNS failure, a refused connection or a TLS error fails the call, and the endpoint is not stored.
The IDs and values in the verification payload are samples — they do not refer to real objects in your account. Make sure your handler tolerates unknown IDs, or acknowledge the request before processing it.
Register the final URL. Only the final HTTP status is evaluated, so a URL that redirects can pass verification even though what your service receives may differ from a live notification.
The stored URL
Theendpoint value in the response is the normalized URL — the exact string Return Helper stores, and the string later duplicate checks compare against. It can differ from what you submitted. Keep the returned value, not your own input.
Idempotency
Thex-returnhelper-idempotency-key header is optional. A call without it runs normally, with no protection against duplicates. See Idempotency.
Errors
Every failure below arrives as HTTP200 with meta.status 400, meta.errorCode VALIDATION_FAILED, and the message under meta.error.endpoint.
| Condition | Message |
|---|---|
| Not a valid absolute URL | Invalid URL format: {endpoint} |
| Longer than 255 characters | Endpoint must be 255 characters or fewer. |
| Scheme is not HTTPS | Endpoint must use HTTPS. Received scheme: {scheme} |
| Loopback, private-network or link-local address | Endpoint must be publicly reachable. Private, loopback and link-local addresses are not allowed. |
| Already registered by your account | This endpoint is already registered. |
| Account is at the maximum | Maximum 5 endpoints allowed. Delete an existing endpoint before adding a new one. |
| Verification request returned a non-2xx status | Endpoint returned {statusCode} ({statusCodeNumber}). It must return a 2xx status to be registered. |
| No response within the timeout | Endpoint did not respond within 30 seconds. |
| Host could not be resolved | Could not resolve host: {host} |
| Connection refused or dropped | Could not connect to {host}. Check that the service is running and that our requests are not blocked. |
| TLS certificate validation failed | TLS certificate validation failed for {host}. |
{
"correlationId": "0HNCJ2K1P9RQ4:00000003",
"meta": {
"status": 400,
"data": {},
"errorCode": "VALIDATION_FAILED",
"error": {
"endpoint": "Maximum 5 endpoints allowed. Delete an existing endpoint before adding a new one."
}
}
}
Related
- List notification endpoints
- Delete a notification endpoint
- Webhooks — event list, payloads and signature verification.
Authorizations
Your API key
Your API token — keep this private
Body
application/json
HTTPS URL to receive webhook notifications. Maximum 255 characters after normalization, must be publicly reachable, and must answer the verification request with a 2xx status within 30 seconds.
Example:
"https://acme.example/hooks/returnhelper"
Response
Success — data carries the stored endpoint and its identifier. The endpoint value is the normalized URL that Return Helper stored, which can differ from the submitted value.
Show child attributes
Show child attributes