Products
Datacenter proxies from $19/mo Rotating proxies from $25/mo ISP proxies from $33/mo Dedicated proxies from $3.50/mo UDP proxies from $5/mo Try proxies
Use cases
Data & scraping AI services Social media & messaging E-commerce & finance Media & entertainment Marketing & ads Automation & tools All use cases →
Pricing
Full pricing table All locations Money-back guarantee
Resources
Dashboard guide API reference API and MCP Setup guides FAQ Blog For business About us Affiliate program
New dashboard
English
English Русский

Webhooks

9 endpoints · base URL https://papaproxy.net/account_new · authentication

List webhook event types

GET/api/v1/customer/webhooks/events
API key required scope webhooks

Event types you can subscribe a webhook endpoint to.

Request example Try it in the Dashboard

cURL
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks/events" \
  -H "Authorization: Bearer $PAPAPROXY_API_KEY"
Python
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())
Node.js
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
<?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));
Go
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

  • 200 Event types you can subscribe to. · 1 fields
    Example response · JSON
    {
      "events": [
        "deposit.completed",
        "payment.failed",
        "payment.succeeded",
        "service.expiring",
        "service.provisioned",
        "service.renewed",
        "service.suspended",
        "service.terminated",
        "wallet.balance_low"
      ]
    }
    FieldTypeDescription
    events requiredarray of stringEvent types the endpoint is subscribed to.
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 429 Too 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

GET/api/v1/customer/webhooks
API key required scope webhooks

List your webhook endpoints.

Request example Try it in the Dashboard

cURL
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks" \
  -H "Authorization: Bearer $PAPAPROXY_API_KEY"
Python
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())
Node.js
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
<?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));
Go
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

  • 200 Your webhook endpoints. · 10 fields
    Example 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
      }
    ]
    FieldTypeDescription
    [].id requiredstring (uuid)Unique ID.
    [].url requiredstring
    [].secret_prefix requiredstringFirst characters of the signing secret.
    [].events requiredarray of stringEvent types the endpoint is subscribed to.
    [].descriptionstring, nullable
    [].is_active requiredbooleanWhether it's active.
    [].disabled_reasonstring, nullableWhy the endpoint was disabled, if it was.
    [].consecutive_failuresintegerFailed deliveries in a row.Default: 0
    [].created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    [].updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 429 Too 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

POST/api/v1/customer/webhooks
API key required scope webhooks

Register 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

FieldTypeDescription
url requiredstringMin length: 8Max length: 2048
events requiredarray of stringEvent types the endpoint is subscribed to.Min items: 1
descriptionstring, nullableMax length: 255

Request example Try it in the Dashboard

cURL
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"]}'
Python
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())
Node.js
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
<?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));
Go
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

  • 201 Create response — includes the raw secret exactly once. · 11 fields
    Example 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"
    }
    FieldTypeDescription
    id requiredstring (uuid)Unique ID.
    url requiredstring
    secret_prefix requiredstringFirst characters of the signing secret.
    events requiredarray of stringEvent types the endpoint is subscribed to.
    descriptionstring, nullable
    is_active requiredbooleanWhether it's active.
    disabled_reasonstring, nullableWhy the endpoint was disabled, if it was.
    consecutive_failuresintegerFailed deliveries in a row.Default: 0
    created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
    secret requiredstring
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 422 Validation error, an http URL, or an unknown event type.
    Example · JSON
    {
      "detail": "Only https URLs are allowed"
    }
  • 429 Too 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

GET/api/v1/customer/webhooks/{endpoint_id}
API key required scope webhooks

Get one of your webhook endpoints.

Parameters

FieldTypeDescription
endpoint_id (path) requiredstring (uuid)ID of the webhook endpoint.

Request example Try it in the Dashboard

cURL
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $PAPAPROXY_API_KEY"
Python
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())
Node.js
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
<?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));
Go
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

  • 200 The webhook endpoint. · 10 fields
    Example 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
    }
    FieldTypeDescription
    id requiredstring (uuid)Unique ID.
    url requiredstring
    secret_prefix requiredstringFirst characters of the signing secret.
    events requiredarray of stringEvent types the endpoint is subscribed to.
    descriptionstring, nullable
    is_active requiredbooleanWhether it's active.
    disabled_reasonstring, nullableWhy the endpoint was disabled, if it was.
    consecutive_failuresintegerFailed deliveries in a row.Default: 0
    created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 404 Webhook endpoint not found, or it doesn't belong to your account. — error format
  • 422 Validation error: a field is missing or has the wrong type or value.
    Example · JSON
    {
      "detail": "Validation error"
    }
  • 429 Too 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

PATCH/api/v1/customer/webhooks/{endpoint_id}
API key required scope webhooks

Change 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

FieldTypeDescription
endpoint_id (path) requiredstring (uuid)ID of the webhook endpoint.

Request body

FieldTypeDescription
urlstring, nullableMin length: 8Max length: 2048
eventsarray of string, nullableEvent types the endpoint is subscribed to.Min items: 1
descriptionstring, nullableMax length: 255
is_activeboolean, nullableWhether it's active.

Request example Try it in the Dashboard

cURL
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"]}'
Python
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())
Node.js
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
<?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));
Go
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

  • 200 The updated webhook endpoint. · 10 fields
    Example 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"
    }
    FieldTypeDescription
    id requiredstring (uuid)Unique ID.
    url requiredstring
    secret_prefix requiredstringFirst characters of the signing secret.
    events requiredarray of stringEvent types the endpoint is subscribed to.
    descriptionstring, nullable
    is_active requiredbooleanWhether it's active.
    disabled_reasonstring, nullableWhy the endpoint was disabled, if it was.
    consecutive_failuresintegerFailed deliveries in a row.Default: 0
    created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 404 Webhook endpoint not found, or it doesn't belong to your account. — error format
  • 422 Validation error, an http URL, or an unknown event type.
    Example · JSON
    {
      "detail": "Only https URLs are allowed"
    }
  • 429 Too 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

DELETE/api/v1/customer/webhooks/{endpoint_id}
API key required scope webhooks

Delete a webhook endpoint. Deliveries to it stop immediately.

Parameters

FieldTypeDescription
endpoint_id (path) requiredstring (uuid)ID of the webhook endpoint.

Request example Try it in the Dashboard

cURL
curl -X DELETE "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $PAPAPROXY_API_KEY"
Python
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())
Node.js
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
<?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));
Go
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

  • 200 Generic message response. · 1 fields
    Example response · JSON
    {
      "message": "ok"
    }
    FieldTypeDescription
    message requiredstring
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 404 Webhook endpoint not found, or it doesn't belong to your account. — error format
  • 422 Validation error: a field is missing or has the wrong type or value.
    Example · JSON
    {
      "detail": "Validation error"
    }
  • 429 Too 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

GET/api/v1/customer/webhooks/{endpoint_id}/deliveries
API key required scope webhooks

Recent 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

FieldTypeDescription
endpoint_id (path) requiredstring (uuid)ID of the webhook endpoint.
limit (query)integerPage size.Minimum: 1Maximum: 50Default: 50

Request example Try it in the Dashboard

cURL
curl -X GET "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/deliveries" \
  -H "Authorization: Bearer $PAPAPROXY_API_KEY"
Python
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())
Node.js
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
<?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));
Go
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

  • 200 Recent deliveries, newest first. · 12 fields
    Example 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
      }
    ]
    FieldTypeDescription
    [].id requiredstring (uuid)Unique ID.
    [].event_id requiredstring (uuid)
    [].endpoint_id requiredstring (uuid)
    [].event_type requiredstring
    [].status requiredstring
    [].attempts requiredinteger
    [].next_attempt_atstring (date-time), nullable
    [].last_response_codeinteger, nullable
    [].last_response_bodystring, nullable
    [].last_errorstring, nullable
    [].created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    [].updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 404 Webhook endpoint not found, or it doesn't belong to your account. — error format
  • 422 Validation error: a field is missing or has the wrong type or value.
    Example · JSON
    {
      "detail": "Validation error"
    }
  • 429 Too 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

POST/api/v1/customer/webhooks/{endpoint_id}/test
API key required scope webhooks

Send 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

FieldTypeDescription
endpoint_id (path) requiredstring (uuid)ID of the webhook endpoint.

Request example Try it in the Dashboard

cURL
curl -X POST "https://papaproxy.net/account_new/api/v1/customer/webhooks/3fa85f64-5717-4562-b3fc-2c963f66afa6/test" \
  -H "Authorization: Bearer $PAPAPROXY_API_KEY"
Python
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())
Node.js
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
<?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));
Go
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

  • 201 The test delivery that was created. · 12 fields
    Example 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
    }
    FieldTypeDescription
    id requiredstring (uuid)Unique ID.
    event_id requiredstring (uuid)
    endpoint_id requiredstring (uuid)
    event_type requiredstring
    status requiredstring
    attempts requiredinteger
    next_attempt_atstring (date-time), nullable
    last_response_codeinteger, nullable
    last_response_bodystring, nullable
    last_errorstring, nullable
    created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 404 Webhook endpoint not found, or it doesn't belong to your account. — error format
  • 422 Validation error: a field is missing or has the wrong type or value.
    Example · JSON
    {
      "detail": "Validation error"
    }
  • 429 Too 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

POST/api/v1/customer/webhooks/deliveries/{delivery_id}/redeliver
API key required scope webhooks

Send 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

FieldTypeDescription
delivery_id (path) requiredstring (uuid)ID of the delivery.

Request example Try it in the Dashboard

cURL
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"
Python
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())
Node.js
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
<?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));
Go
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

  • 201 The new delivery attempt. · 12 fields
    Example 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
    }
    FieldTypeDescription
    id requiredstring (uuid)Unique ID.
    event_id requiredstring (uuid)
    endpoint_id requiredstring (uuid)
    event_type requiredstring
    status requiredstring
    attempts requiredinteger
    next_attempt_atstring (date-time), nullable
    last_response_codeinteger, nullable
    last_response_bodystring, nullable
    last_errorstring, nullable
    created_atstring (date-time), nullableWhen it was created (ISO 8601, UTC).
    updated_atstring (date-time), nullableWhen it was last changed (ISO 8601, UTC).
  • 401 The API key is missing, malformed, revoked, or expired, or the account is inactive.
    Example · JSON
    {
      "detail": "Invalid or revoked API key."
    }
  • 403 The API key lacks scope webhooks.
    Example · JSON
    {
      "detail": "API key is missing required scope: webhooks"
    }
  • 404 Delivery not found, or it doesn't belong to your account. — error format
  • 422 Validation error: a field is missing or has the wrong type or value.
    Example · JSON
    {
      "detail": "Validation error"
    }
  • 429 Too 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.