Webhooks
9 endpoints · base URL https://papaproxy.net/account_new · authentication
List webhook event types
/api/v1/customer/webhooks/eventswebhooksEvent types you can subscribe a webhook endpoint to.
Request example Try it in the Dashboard
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks/events" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.get(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/events",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/events", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/events');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://papaproxy.net/account_new/api/v1/customer/webhooks/events", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
200Event types you can subscribe to. · 1 fieldsExample response · JSON{ "events": [ "deposit.completed", "payment.failed", "payment.succeeded", "service.expiring", "service.provisioned", "service.renewed", "service.suspended", "service.terminated", "wallet.balance_low" ] }Field Type Description eventsrequiredarray of string Event types the endpoint is subscribed to. 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
List webhook endpoints
/api/v1/customer/webhookswebhooksList your webhook endpoints.
Request example Try it in the Dashboard
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.get(
"https://papaproxy.net/account_new/api/v1/customer/webhooks",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://papaproxy.net/account_new/api/v1/customer/webhooks", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
200Your webhook endpoints. · 10 fieldsExample response · JSON[ { "id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "url": "https://example.com/webhooks/papaproxy", "secret_prefix": "whsec_3p", "events": [ "service.provisioned", "wallet.balance_low" ], "description": null, "is_active": true, "disabled_reason": null, "consecutive_failures": 0, "created_at": "2026-11-07T14:31:39.000403Z", "updated_at": null } ]Field Type Description [].idrequiredstring (uuid) Unique ID. [].urlrequiredstring [].secret_prefixrequiredstring First characters of the signing secret. [].eventsrequiredarray of string Event types the endpoint is subscribed to. [].descriptionstring, nullable [].is_activerequiredboolean Whether it's active. [].disabled_reasonstring, nullable Why the endpoint was disabled, if it was. [].consecutive_failuresinteger Failed deliveries in a row.Default: 0[].created_atstring (date-time), nullable When it was created (ISO 8601, UTC). [].updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Create a webhook endpoint
/api/v1/customer/webhookswebhooksRegister an HTTPS URL to receive event notifications. The signing secret (whsec_…) is returned only once, in this response: store it to verify the X-FB-Signature header of each delivery (see Webhooks in the overview).
Only https URLs are accepted; an http URL returns 422 (Only https URLs are allowed). Every value in events must come from GET /api/v1/customer/webhooks/events; an unknown event type returns 422.
Request body
| Field | Type | Description |
|---|---|---|
url required | string | Min length: 8Max length: 2048 |
events required | array of string | Event types the endpoint is subscribed to.Min items: 1 |
description | string, nullable | Max length: 255 |
Request example Try it in the Dashboard
curl -X POST "https://papaproxy.net/account_new/api/v1/customer/webhooks" \
-H "Authorization: Bearer $PAPAPROXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhooks/papaproxy", "events": ["service.provisioned", "wallet.balance_low"]}'import os
import requests
resp = requests.post(
"https://papaproxy.net/account_new/api/v1/customer/webhooks",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
json={
"url": "https://example.com/webhooks/papaproxy",
"events": [
"service.provisioned",
"wallet.balance_low"
]
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com/webhooks/papaproxy",
"events": [
"service.provisioned",
"wallet.balance_low"
]
}),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.com/webhooks/papaproxy',
'events' => ['service.provisioned', 'wallet.balance_low']
]),
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://papaproxy.net/account_new/api/v1/customer/webhooks", strings.NewReader(`{"url": "https://example.com/webhooks/papaproxy", "events": ["service.provisioned", "wallet.balance_low"]}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
201Create response — includes the raw secret exactly once. · 11 fieldsExample response · JSON{ "id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "url": "https://example.com/webhooks/papaproxy", "secret_prefix": "whsec_3p", "events": [ "service.provisioned", "wallet.balance_low" ], "description": null, "is_active": true, "disabled_reason": null, "consecutive_failures": 0, "created_at": "2026-11-07T14:31:39.000403Z", "updated_at": null, "secret": "whsec_3pQ9xVn2LmA7cR8sK1tY5bZ0wE4uH6jD" }Field Type Description idrequiredstring (uuid) Unique ID. urlrequiredstring secret_prefixrequiredstring First characters of the signing secret. eventsrequiredarray of string Event types the endpoint is subscribed to. descriptionstring, nullable is_activerequiredboolean Whether it's active. disabled_reasonstring, nullable Why the endpoint was disabled, if it was. consecutive_failuresinteger Failed deliveries in a row.Default: 0created_atstring (date-time), nullable When it was created (ISO 8601, UTC). updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). secretrequiredstring 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }422Validation error, anhttpURL, or an unknown event type.Example · JSON{ "detail": "Only https URLs are allowed" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Get a webhook endpoint
/api/v1/customer/webhooks/{endpoint_id}webhooksGet one of your webhook endpoints.
Parameters
| Field | Type | Description |
|---|---|---|
endpoint_id (path) required | string (uuid) | ID of the webhook endpoint. |
Request example Try it in the Dashboard
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.get(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
200The webhook endpoint. · 10 fieldsExample response · JSON{ "id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "url": "https://example.com/webhooks/papaproxy", "secret_prefix": "whsec_3p", "events": [ "service.provisioned", "wallet.balance_low" ], "description": null, "is_active": true, "disabled_reason": null, "consecutive_failures": 0, "created_at": "2026-11-07T14:31:39.000403Z", "updated_at": null }Field Type Description idrequiredstring (uuid) Unique ID. urlrequiredstring secret_prefixrequiredstring First characters of the signing secret. eventsrequiredarray of string Event types the endpoint is subscribed to. descriptionstring, nullable is_activerequiredboolean Whether it's active. disabled_reasonstring, nullable Why the endpoint was disabled, if it was. consecutive_failuresinteger Failed deliveries in a row.Default: 0created_atstring (date-time), nullable When it was created (ISO 8601, UTC). updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }404Webhook endpoint not found, or it doesn't belong to your account. — error format422Validation error: a field is missing or has the wrong type or value.Example · JSON{ "detail": "Validation error" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Update a webhook endpoint
/api/v1/customer/webhooks/{endpoint_id}webhooksChange the URL, event types, or status of a webhook endpoint. The same rules as on creation apply: https URLs only, and event types from GET /api/v1/customer/webhooks/events.
Parameters
| Field | Type | Description |
|---|---|---|
endpoint_id (path) required | string (uuid) | ID of the webhook endpoint. |
Request body
| Field | Type | Description |
|---|---|---|
url | string, nullable | Min length: 8Max length: 2048 |
events | array of string, nullable | Event types the endpoint is subscribed to.Min items: 1 |
description | string, nullable | Max length: 255 |
is_active | boolean, nullable | Whether it's active. |
Request example Try it in the Dashboard
curl -X PATCH "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "Authorization: Bearer $PAPAPROXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhooks/papaproxy", "events": ["service.provisioned"]}'import os
import requests
resp = requests.patch(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
json={
"url": "https://example.com/webhooks/papaproxy",
"events": [
"service.provisioned"
]
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"url": "https://example.com/webhooks/papaproxy",
"events": [
"service.provisioned"
]
}),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.com/webhooks/papaproxy',
'events' => ['service.provisioned']
]),
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("PATCH", "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6", strings.NewReader(`{"url": "https://example.com/webhooks/papaproxy", "events": ["service.provisioned"]}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
200The updated webhook endpoint. · 10 fieldsExample response · JSON{ "id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "url": "https://example.com/webhooks/papaproxy", "secret_prefix": "whsec_3p", "events": [ "service.provisioned" ], "description": null, "is_active": true, "disabled_reason": null, "consecutive_failures": 0, "created_at": "2026-11-07T14:31:39.000403Z", "updated_at": "2026-11-07T14:31:41.801663Z" }Field Type Description idrequiredstring (uuid) Unique ID. urlrequiredstring secret_prefixrequiredstring First characters of the signing secret. eventsrequiredarray of string Event types the endpoint is subscribed to. descriptionstring, nullable is_activerequiredboolean Whether it's active. disabled_reasonstring, nullable Why the endpoint was disabled, if it was. consecutive_failuresinteger Failed deliveries in a row.Default: 0created_atstring (date-time), nullable When it was created (ISO 8601, UTC). updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }404Webhook endpoint not found, or it doesn't belong to your account. — error format422Validation error, anhttpURL, or an unknown event type.Example · JSON{ "detail": "Only https URLs are allowed" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Delete a webhook endpoint
/api/v1/customer/webhooks/{endpoint_id}webhooksDelete a webhook endpoint. Deliveries to it stop immediately.
Parameters
| Field | Type | Description |
|---|---|---|
endpoint_id (path) required | string (uuid) | ID of the webhook endpoint. |
Request example Try it in the Dashboard
curl -X DELETE "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.delete(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("DELETE", "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
200Generic message response. · 1 fieldsExample response · JSON{ "message": "ok" }Field Type Description messagerequiredstring 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }404Webhook endpoint not found, or it doesn't belong to your account. — error format422Validation error: a field is missing or has the wrong type or value.Example · JSON{ "detail": "Validation error" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
List webhook deliveries
/api/v1/customer/webhooks/{endpoint_id}/deliverieswebhooksRecent delivery attempts for this endpoint, with response status codes. A failed delivery is retried 5 more times over about 8.5 hours, then marked as failed.
Parameters
| Field | Type | Description |
|---|---|---|
endpoint_id (path) required | string (uuid) | ID of the webhook endpoint. |
limit (query) | integer | Page size.Minimum: 1Maximum: 50Default: 50 |
Request example Try it in the Dashboard
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.get(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
200Recent deliveries, newest first. · 12 fieldsExample response · JSON[ { "id": "f2ec0963-48bb-52a5-966b-07b7e36a835d", "event_id": "1529f6ec-af23-594f-941d-a694f3dde477", "endpoint_id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "event_type": "ping", "status": "pending", "attempts": 0, "next_attempt_at": "2026-11-07T14:31:42.661857Z", "last_response_code": null, "last_response_body": null, "last_error": null, "created_at": "2026-11-07T14:31:42.656390Z", "updated_at": null } ]Field Type Description [].idrequiredstring (uuid) Unique ID. [].event_idrequiredstring (uuid) [].endpoint_idrequiredstring (uuid) [].event_typerequiredstring [].statusrequiredstring [].attemptsrequiredinteger [].next_attempt_atstring (date-time), nullable [].last_response_codeinteger, nullable [].last_response_bodystring, nullable [].last_errorstring, nullable [].created_atstring (date-time), nullable When it was created (ISO 8601, UTC). [].updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }404Webhook endpoint not found, or it doesn't belong to your account. — error format422Validation error: a field is missing or has the wrong type or value.Example · JSON{ "detail": "Validation error" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Send a test event
/api/v1/customer/webhooks/{endpoint_id}/testwebhooksSend a ping test event to this endpoint to check that it receives and verifies deliveries. The delivery is queued and usually arrives within a minute.
Parameters
| Field | Type | Description |
|---|---|---|
endpoint_id (path) required | string (uuid) | ID of the webhook endpoint. |
Request example Try it in the Dashboard
curl -X POST "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/test" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.post(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/test",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/test", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/test');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/test", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
201The test delivery that was created. · 12 fieldsExample response · JSON{ "id": "f2ec0963-48bb-52a5-966b-07b7e36a835d", "event_id": "1529f6ec-af23-594f-941d-a694f3dde477", "endpoint_id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "event_type": "ping", "status": "pending", "attempts": 0, "next_attempt_at": "2026-11-07T14:31:42.661857Z", "last_response_code": null, "last_response_body": null, "last_error": null, "created_at": "2026-11-07T14:31:42.656390Z", "updated_at": null }Field Type Description idrequiredstring (uuid) Unique ID. event_idrequiredstring (uuid) endpoint_idrequiredstring (uuid) event_typerequiredstring statusrequiredstring attemptsrequiredinteger next_attempt_atstring (date-time), nullable last_response_codeinteger, nullable last_response_bodystring, nullable last_errorstring, nullable created_atstring (date-time), nullable When it was created (ISO 8601, UTC). updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }404Webhook endpoint not found, or it doesn't belong to your account. — error format422Validation error: a field is missing or has the wrong type or value.Example · JSON{ "detail": "Validation error" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Redeliver an event
/api/v1/customer/webhooks/deliveries/{delivery_id}/redeliverwebhooksSend a past delivery again, for example after fixing your endpoint. The event ID stays the same, so your handler can skip events it has already processed.
Parameters
| Field | Type | Description |
|---|---|---|
delivery_id (path) required | string (uuid) | ID of the delivery. |
Request example Try it in the Dashboard
curl -X POST "https://papaproxy.net/account_new/api/v1/customer/webhooks/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/redeliver" \ -H "Authorization: Bearer $PAPAPROXY_API_KEY"
import os
import requests
resp = requests.post(
"https://papaproxy.net/account_new/api/v1/customer/webhooks/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/redeliver",
headers={"Authorization": f"Bearer {os.environ['PAPAPROXY_API_KEY']}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())const resp = await fetch("https://papaproxy.net/account_new/api/v1/customer/webhooks/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/redeliver", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAPAPROXY_API_KEY}`,
},
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
console.log(await resp.json());<?php
$ch = curl_init('https://papaproxy.net/account_new/api/v1/customer/webhooks/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/redeliver');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PAPAPROXY_API_KEY'),
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
var_dump($status, json_decode($response, true));package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://papaproxy.net/account_new/api/v1/customer/webhooks/deliveries/3fa85f64-5717-4562-b3fc-2c963f66afa6/redeliver", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAPAPROXY_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}Responses
201The new delivery attempt. · 12 fieldsExample response · JSON{ "id": "fcf4a431-710d-5edd-a55c-9a4efc65da19", "event_id": "3db339fc-c187-5608-b68a-7ee93c944424", "endpoint_id": "24018d46-98dc-5a0a-8ca7-dbde79739ab7", "event_type": "ping", "status": "pending", "attempts": 0, "next_attempt_at": "2026-11-07T14:31:44.554104Z", "last_response_code": null, "last_response_body": null, "last_error": null, "created_at": "2026-11-07T14:31:44.548818Z", "updated_at": null }Field Type Description idrequiredstring (uuid) Unique ID. event_idrequiredstring (uuid) endpoint_idrequiredstring (uuid) event_typerequiredstring statusrequiredstring attemptsrequiredinteger next_attempt_atstring (date-time), nullable last_response_codeinteger, nullable last_response_bodystring, nullable last_errorstring, nullable created_atstring (date-time), nullable When it was created (ISO 8601, UTC). updated_atstring (date-time), nullable When it was last changed (ISO 8601, UTC). 401The API key is missing, malformed, revoked, or expired, or the account is inactive.Example · JSON{ "detail": "Invalid or revoked API key." }403The API key lacks scopewebhooks.Example · JSON{ "detail": "API key is missing required scope: webhooks" }404Delivery not found, or it doesn't belong to your account. — error format422Validation error: a field is missing or has the wrong type or value.Example · JSON{ "detail": "Validation error" }429Too many requests: the per-account limit is 60 requests per minute, shared by all keys and the MCP server. Retry with exponential backoff.Example · JSON{ "detail": "Too Many Requests" }
Last updated: November 9, 2026. Generated from the OpenAPI 3.1 specification (API version 0.1.0). Markdown version for AI agents.