← Back to documentation

Endpoint Management

Create and maintain endpoints that accept and forward traffic.

19 min read

An endpoint is an inbound relay URL. It examines the requests and sends the accepted traffic to the configured destinations.

Purpose#

Use this guide to:

  • Create and edit endpoints.
  • Set the method, the payload format, the retries, and the security.
  • Set the field validation.
  • Attach relay targets as destinations.
  • Change the endpoint URL and the lifecycle state.

Before you start#

  • A signed-in account.
  • Relay targets that exist already.
  • A relay target must be Available before you can select it as a destination. A platform email target needs the confirmation. A custom SMTP email target needs a successful connection test.

Procedure#

1. Create endpoint#

  1. Open Endpoints and select Create endpoint.
  2. In Details, enter these values:
  • The name. This value is necessary, with a maximum of 100 characters.
  • The description. This value is optional, with a maximum of 500 characters.
  • The accepted HTTP method.
  • The expected payload format. For GET and HEAD, only None and the query parameter formats are available.
  1. Save the endpoint.

2. Configure details behavior#

  • Any accepts every method. GET and HEAD still have no body.
  • For a body-capable method (JSON, XML, Form, text/plain), the payload format must match the incoming Content-Type. A different Content-Type returns HTTP 415 and records UNSUPPORTED_MEDIA_TYPE.
  • The None format and the query parameter formats accept every Content-Type value.
  • Ignore Content-Type headers: if this control is enabled, PayloadRelay does not examine the Content-Type, and it parses the body in the configured format. All the other endpoint tests still apply. Use this control if a caller sends a wrong header or no header, but gives a payload in the configured format.

3. Configure delivery retries#

Set the delivery retries for each webhook destination in the Outputs tab:

  • The default is 0. There are no retries.
  • You can set a value to the maximum of your plan for each webhook.
  • The plan limits are Sandbox 1, Solo 3, and Team trial, Team, and Scale 5. For a custom plan, the agreement of the organization sets the limit.
  • Sandbox and Solo use the standard schedule. On the Team trial, Team, Scale, and an eligible custom plan, you can select an advanced schedule and custom retry status codes.
  • A target with no retry configuration for the user uses an automatic retry schedule when PayloadRelay supports it. The same plan limit applies.

4. Configure security#

The Security tab supports these controls:

  • Inbound authentication: None, Basic, Bearer token, API key header, or HMAC. For the provider presets, see HMAC Inbound Verification.
  • Human verification: None, Cloudflare Turnstile, Google reCAPTCHA.
  • Required request headers, with a maximum of 20 exact-value matches. A header name uses the normal HTTP token syntax, and the match ignores the case. A header name cannot be Authorization, Host, Content-Length, or a hop-by-hop or proxy header. PayloadRelay removes the spaces from a value when it saves the value, and the value cannot be empty. An incoming value must match exactly, with the same case and with no space removal. The required headers do not block a browser CORS preflight test.
  • CORS origins. Enter one exact scheme://host[:port] value in each line. A blank value permits every browser origin.
  • IP allowlist. This control limits the traffic to IP addresses or CIDR blocks. The related Allowed IP version control is in the Details tab, and it can limit the traffic to IPv4 or IPv6. The two controls apply to a webhook endpoint only. See IP Allowlists.

Rules:

  • A captcha needs a body-capable method and a JSON, FORM, or XML payload format. It is not available for None, text/plain, or a query parameter format.
  • The captcha supports Cloudflare Turnstile and Google reCAPTCHA. PayloadRelay stores the configured secret encrypted, and the API never returns it.
  • If you change the captcha provider, enter the secret of the new provider. PayloadRelay deletes the secret of the old provider.
  • PayloadRelay accepts a reCAPTCHA token when Google returns success. PayloadRelay does not apply a reCAPTCHA v3 score. For bot protection, use a reCAPTCHA v2 checkbox key or Cloudflare Turnstile.
  • The captcha field name is a JSON or form field key, a dot path such as captcha.token, or an XPath selector for XML. An XML selector must be in the XPath subset for XML. A stored XML selector outside the subset returns HTTP 400 and records UNSUPPORTED_SELECTOR. The default field names are g-recaptcha-response for reCAPTCHA and cf-turnstile-response for Turnstile. A missing token or an invalid token returns a 4xx status and records CAPTCHA_FAILED.
  • To keep the stored values during an edit, leave the secret fields blank.
  • Include captcha field in payload sets if the captcha token goes to the destinations, with Google Sheets. For a JSON payload and a form payload, PayloadRelay removes the token before the transforms and the delivery when this control is off. PayloadRelay sends the XML with no change.

5. Configure field validation#

Field validation is available in these conditions:

  • The payload format is JSON, FORM, XML, Query Parameters, or Query Parameters (Base64 JSON).
  • GET and HEAD support the field validation only with a query parameter format.

Supported validation types:

  • ANY, STRING, INTEGER, FLOAT, BOOLEAN, EMAIL, REGEX

ANY does no type test. Use it with Required if the field must only exist.

Notes:

  • Each endpoint can have a maximum of 20 rules. A field name and a selector can have a maximum of 200 characters. You cannot use the same value two times.
  • A JSON, form, and query payload supports a dot-path field such as user.email or items.0.id. A numeric path segment gives the index in an array. PayloadRelay does not support the bracket notation such as items[0].id.
  • An XML field name is an XPath selector in the XPath subset for XML. PayloadRelay rejects a selector outside the subset when you save the rule. At relay time, a stored rule with a selector outside the subset returns HTTP 400 and records UNSUPPORTED_SELECTOR.
  • An XML payload can have a maximum of 100 nested element levels.
  • A type test uses the native JSON types when they are available. INTEGER, FLOAT, and BOOLEAN also accept a text value that holds a valid value, such as "1", "1.5", or "true". This applies to a JSON string and to a form, query, or XML value. REGEX and EMAIL apply to text values.
  • For a JSON endpoint with one field validation rule or more, the payload root must be a JSON object. An array, a scalar, or an empty body returns HTTP 400 and records FIELD_VALIDATION_FAILED.
  • A regex entry needs a valid Java-compatible regular expression of 500 characters or fewer. The matching has a time limit at relay time.
  • The text/plain format and the None format do not apply the field validation.
  • Query Parameters always makes a JSON object, and it supports the standard field validation rules. A necessary query parameter field must be in the URL. An explicit empty value (?key=) is present but blank. A Required rule rejects it. An optional INTEGER, FLOAT, BOOLEAN, or EMAIL rule also rejects it. An absent parameter passes an optional rule.
  • Query Parameters (Base64 JSON) supports the field validation when the root of the decoded JSON is an object. If the endpoint has one field validation rule or more, a decoded array, a scalar, or an empty payload returns HTTP 400 and records FIELD_VALIDATION_FAILED. With no rules, PayloadRelay sends an array and a scalar JSON value to the relay targets.

6. Configure request body filters#

A request body filter is an accept rule or a reject rule on the endpoint. The filters apply before the captcha, the field validation, the transforms, the quota consumption, and the delivery. All the configured filters must pass.

Supported filter types:

  • CONTAINS: the raw body or the query string contains the configured value. The comparison is case-sensitive.
  • MATCHES: the raw body or the query string is the same as the configured value.
  • DOES_NOT_CONTAIN: the raw body or the query string does not contain the configured value.
  • REGEX: a Java-compatible regular expression with a time limit on the partial matching.

Limits and behavior:

  • Each endpoint can have a maximum of 10 unique body filter rules.
  • A filter value is necessary and has a maximum of 4,096 characters. A regex pattern must also agree with the safe-regex limit.
  • A JSON, XML, and text payload uses the raw UTF-8 request body. A form endpoint uses the raw form body. A query-parameter format uses the raw URL query string.
  • A None payload clears the body filters, and PayloadRelay does not apply them.
  • An HTTP request body filter that fails returns HTTP 400 and records REQUEST_BODY_FILTER_FAILED. An email body-as-payload filter records the same outcome and returns SMTP 550 to the sender.

7. Configure outputs#

  1. In Outputs, attach one relay target or more. Each destination attaches an existing relay target in your account or organization to this endpoint. Its type is the target type (EMAIL, WEBHOOK, SLACK, DISCORD, GOOGLE_SHEETS, MICROSOFT_TEAMS, PAGERDUTY, or TELEGRAM). The API rejects a target with a different type and a target from a different organization.
  2. Use Delivery enabled to keep a destination configured and stop the delivery to that target. A disabled endpoint stops every destination. A disabled destination stops that target only. The other enabled destinations still receive the deliveries.
  3. Configure the values for each destination:
  • Email: the subject, the Reply-To behavior, and the body format. A subject template removes CR, LF, and NUL after the formatting, to prevent a header injection. A blank formatted subject uses No subject. A Reply-To value must be an email address. A manual value and a fallback value cannot contain CR or LF.
  • Available email body formats:
  • RAW_PAYLOAD: the raw payload with formatting. A text payload or an XML payload arrives as its text, without JSON quotes.
  • RAW_PAYLOAD_ROWS: the raw payload with one field in each row, and an indentation of two spaces for each nested level
  • TEXT: plain text, with an optional custom body template
  • HTML: HTML, with an optional custom body template. PayloadRelay escapes each value that the template inserts, also {{email.htmlBody}}. PayloadRelay does not change the markup that you write in the template. It does not remove a javascript: link from that markup.
  • Slack: the Markdown control, on or off. When it is on, PayloadRelay escapes &, <, and > in each inserted value. So a mention such as <!channel> works only in the literal text of a template. Refer to Slack Incoming Webhooks.
  • Discord: the TTS control, on or off, and an optional cut of a long message. The cut is off by default. If the cut is off, Activity records Discord content that is too large as a failed delivery. A generated message and a template message mention nobody. A message template ignores the cut control. Refer to Message Templates.
  • Microsoft Teams: optional message templates. PayloadRelay stores the destination credentials on the relay target.
  • PagerDuty: PayloadRelay stores the integration key and the severity on the relay target. Create one PagerDuty target for each service or integration key.
  • Telegram: optional message templates. PayloadRelay stores the bot token and the chat ID on the relay target.
  • Google Sheets:
    • Save all fields to Sheet (on by default)
    • If Save all fields to Sheet is off, configure the exact fields to keep
  • Webhook URL:
  • Enforce HTTPS: PayloadRelay rejects the delivery if the target URL is not HTTPS. This control is enabled by default. An HTTPS connection always uses the normal TLS certificate validation. If you disable this control, PayloadRelay still rejects an invalid certificate.
  • Outbound HTTP method: the outbound method, POST, PUT, or PATCH. The default is POST. If an API update omits the method, the saved method stays.
  • Authentication: None, Basic, Bearer, or API Key. A Basic username cannot contain : or control characters.
  • Custom headers: a maximum of 25 key-value pairs. A name has a maximum of 128 characters. A saved value has a maximum of 4,096 characters, and it can use a template variable such as {{fieldname}}, {{originating_ip}}, {{uuid}}, and {{email.subject}}. Mark a header that holds a credential as sensitive. PayloadRelay encrypts these values, and it does not show them after you save. Each header name must be unique. A header name cannot be a restricted HTTP header, it cannot conflict with the webhook authentication, and it cannot be the same as an outbound HMAC signature header, timestamp header, or previous-signature header.

    After the template variable resolution, PayloadRelay removes CR and LF from the outbound header values, and it limits a value to 8,192 characters. If PayloadRelay makes a value shorter, the delivery log records a warning for the target.

  • Custom body: an optional body template with template variables. The saved template has a maximum of 65,536 characters. The formatted body has a maximum of 1 MiB. A custom body can use the inbound {{headers.Name}} and {{query.name}} values. PayloadRelay inserts each value as raw text, without JSON escaping. A value that contains ", \, or a line break can make a JSON body invalid. In a JSON body, insert only the values that cannot contain these characters. For a channel-specific template, use Message Templates on a Slack, Discord, Microsoft Teams, or Telegram destination.
  • Content-Type: an outbound content type that replaces the default. It must be a valid MIME type with a maximum of 100 characters.
  • Output payload format: Same as inbound, JSON, XML, Form-encoded, or Plain Text. PayloadRelay converts the payload after the transform rules. For XML, PayloadRelay puts a text payload that is not well-formed XML in a <payload> element.
  • Forward incoming headers: PayloadRelay forwards all the headers or the selected headers from the incoming request. Forward all skips each cf-* header from the Cloudflare edge of PayloadRelay. If you select a cf-* header by name, PayloadRelay forwards it.
  • Forward response body: after a successful webhook delivery, PayloadRelay sends its response body to a different supported target. PayloadRelay does not send partial response data when the response is too large. Activity shows the response-forward attempt as failed. PayloadRelay asks the destination for an unencoded response with Accept-Encoding: identity. If the response still has a content encoding, PayloadRelay does not forward it. Activity then records Destination response used a content encoding. The primary delivery stays a success. A PayloadRelay-to-PayloadRelay chain stops after three hops. The hop count includes the hops through an email endpoint. Slack and Discord can shorten the content to their platform limits.
  • Enable failover delivery: for a webhook destination, PayloadRelay sends the payload to a fallback destination when the primary delivery fails permanently. This occurs after the last configured retry. A response that PayloadRelay cannot retry, for example 404, starts the failover after the first attempt. The supported failover destinations are email, webhook, Slack, Discord, and Microsoft Teams. PayloadRelay does not support a Google Sheets, PagerDuty, or Telegram target for a failover. Refer to Retries and Delivery Behavior.
  1. Save the changes.

Notes:

  • The enabled primary destinations have a limit for each endpoint: Sandbox 2, Solo 3, the Team trial and Team 5, and Scale 10. For a custom plan, the agreement of the organization sets the limit. A disabled destination configuration and a failover row do not count.
  • If a downgrade makes the limit lower, the oldest permitted destinations stay enabled. PayloadRelay disables the extra destinations, and it keeps their configuration.
  • If you remove a destination, the other destinations on the endpoint stay.
  • An endpoint can have no destination. PayloadRelay accepts and records the relay requests, and it sends no delivery.
  • If you delete an endpoint, PayloadRelay deletes its destinations. You cannot delete a relay target while a destination uses it.
  • Configure the failover on the primary webhook destination, and not on the endpoint. A webhook failover destination has its own Outbound HTTP method, Retry policy, Failover delivery retries, retry status codes, and Sign failover requests (HMAC). A different supported failover target uses its automatic retry behavior in the plan limit. Activity records a failover attempt as FAILOVER_TRIGGERED.
  • The failover fills in {{query.*}} and {{email.*}} from the original request. If you save the endpoint with the same failover target, PayloadRelay keeps the failover configuration.
  • The failover also runs while the endpoint is paused. A disabled endpoint stops the failover.

Restricted headers

When PayloadRelay forwards the incoming headers to a webhook target, with Forward all or with specific header names, PayloadRelay always removes these restricted headers:

HeaderReason
HostPayloadRelay sets it for the destination
ConnectionHop-by-hop
Content-LengthPayloadRelay sets it from the outgoing body
Transfer-EncodingHop-by-hop
UpgradeHop-by-hop
Proxy-AuthorizationSecurity-sensitive
Proxy-ConnectionHop-by-hop
TEHop-by-hop
TrailerHop-by-hop
ExpectHop-by-hop
Keep-AliveHop-by-hop
HTTP2-SettingsConnection-specific
AuthorizationSecurity-sensitive. Use the webhook authentication of the destination.
CookieSecurity-sensitive. A session token must not go to a target.
Set-CookieSecurity-sensitive. PayloadRelay must not forward this response header.
Content-TypePayloadRelay sets it from the payload format and the content-type replacement
Accept-EncodingPayloadRelay sets it. The delivery service does not decode a compressed response.
CDN-LoopCloudflare uses it to find a loop. A forwarded value can make Cloudflare reject the delivery to a destination behind Cloudflare.
X-PayloadRelay-Forward-ChainSigned loop-protection metadata that PayloadRelay manages
X-PayloadRelay-Delivery-IdDelivery identity metadata that PayloadRelay manages
X-PayloadRelay-Event-IdEvent identity metadata that PayloadRelay manages
X-PayloadRelay-AttemptDelivery-attempt metadata that PayloadRelay manages

PayloadRelay also removes the endpoint-specific credential headers and validation headers: each configured required request header, the configured inbound API-key header, the inbound HMAC signature header, and the Slack timestamp header when the Slack HMAC preset is active. PayloadRelay never gives these dynamic names to a body template, and it never forwards them automatically. If you select one of them, the protection stays. If the destination needs its own credential, add the value separately as outbound authentication or as a sensitive custom header on the destination.

If Forward all incoming headers is enabled, PayloadRelay removes the static headers and the endpoint-specific headers in the list above. If you add a static restricted name to the list of specific forwarded headers, the API rejects the configuration. So it does not save a value that it ignores. If a name that you saved before is restricted now, PayloadRelay removes it at the next save. PayloadRelay can forward all the other incoming headers.

Google Sheets delivery behavior

  • PayloadRelay adds each accepted payload as a new row.
  • PayloadRelay matches the columns to the field names, and it ignores the case.
  • PayloadRelay creates a missing column automatically, and it uses the field name as the header.
  • For an XML, text/plain, and None flow, payload is the only supported configured field.
  • For a query parameter format, also on GET and HEAD, you can select the individual parsed fields.

8. Configure email ingestion#

Email ingestion permits an endpoint to receive an email as a relay payload. It needs no HTTP request.

  1. In the header of the endpoint editor, select Email ingestion endpoint in the Endpoint type list.
  2. Save the endpoint.
  3. Open the saved endpoint and copy the emailIngestionAddress that the API gives.
  4. Use that address as a recipient in the system that sends the email.
  5. PayloadRelay converts the incoming email into a JSON payload with the sender, the recipients, the subject, the text body and the HTML body, the headers, and the metadata.
  6. PayloadRelay removes the attachments. It relays the text content only.
  7. Each new accepted inbound email consumes one accepted event from the monthly quota. A completed second delivery that PayloadRelay identifies consumes no quota.

Notes:

  • An endpoint is a Webhook endpoint or an Email ingestion endpoint. It cannot be both.
  • A change of the endpoint type clears the values for that type. For example, a change to email clears the inbound authentication, the captcha, the IP limits, the CORS, and the required headers.
  • The endpoint must be enabled to accept an inbound email.
  • Activity shows Email Accepted (EMAIL_INGESTION_ACCEPTED) for an accepted email relay. A rejection uses the most specific outcome that is available, such as Auth Failed (AUTH_FAILED), Body Filter Failed (REQUEST_BODY_FILTER_FAILED), Validation Failed (FIELD_VALIDATION_FAILED), Malformed JSON Payload (MALFORMED_JSON_PAYLOAD), or Email Rejected (EMAIL_INGESTION_REJECTED).

9. Pause and auto-resume#

Pause an endpoint for a period, and do not disable it. During the pause, a webhook request receives 503 Service Unavailable. An inbound email receives a temporary SMTP 451. The two responses create no Request activity row.

To pause an endpoint:

  1. Open the endpoint in the editor.
  2. Select the Pause button beside the enable control.
  3. Select 1 hour, 6 hours, 24 hours, or Custom… for 1 to 43,200 minutes.
  4. Read the badge, such as Paused. The endpoint resumes in 3h 20m.

To resume early:

  • To clear the pause immediately, select Resume now in the pause badge.
  • The endpoint accepts traffic again immediately.

Behavior notes:

  • A webhook request during a pause receives HTTP 503. An inbound email receives SMTP 451. The PayloadRelay mail server keeps the email and sends it again for a maximum of 5 days. If the pause is longer, the mail server returns the email to the SMTP envelope sender.
  • The endpoint resumes after the selected period. You do not have to do anything.
  • A pause is different from a disable. An endpoint with enabled=false returns 404. A paused endpoint returns 503.
  • PayloadRelay keeps the selected resume time until the endpoint resumes automatically, or until you resume it manually.

10. URL rotation and lifecycle actions#

  • Regenerate URL creates a new endpoint URL immediately. The editor discards the unsaved changes, so save the endpoint first.
  • The old URL stops to accept requests immediately.
  • You can enable or disable the endpoint.
  • Delete removes the endpoint and its related Activity history permanently.

11. Failure-rate alerts#

Configure an alert for each endpoint. The alert fires when the failure rate in a rolling window is equal to a threshold or higher. You can also pause the endpoint automatically when an alert fires. For the details, see the Failure-Rate Alerts guide.

Expected result#

  • The endpoint appears with the expected method, format, and security configuration.
  • The accepted traffic appears as Pending while the deliveries are in progress, then it moves to a final outcome. The dashboard shows the label Completed for final ACCEPTED traffic.
  • The selected destinations receive the deliveries.
  • A Google Sheets destination adds rows to the selected spreadsheet and sheet.

Common issues and fixes#

  • "No relay targets": create the targets first.
  • The email destination is not available: make sure that the email target is available.
  • PayloadRelay rejects the Google Sheets field selection: if Save all fields to Sheet is off, add a field. Use payload only for an XML, text/plain, or None endpoint.
  • Validation errors: examine the field names, the types, and the patterns.
  • Captcha errors: make sure that the token field name and the provider secret are correct.
  • Delivery errors: examine the target URL, the authentication, the headers, and the TLS configuration.
  • Unexpected 3xx failures: PayloadRelay does not obey an HTTP redirect. A webhook target must answer directly with a 2xx status code.

Throughput controls#

For each endpoint, you can set Requests per minute in the Details tab. An email endpoint shows Emails per minute. To use the default of your subscription tier, leave it blank. You can also enter a positive integer to the limit of your tier. A request above the effective limit returns 429 Too Many Requests with a Retry-After header, and Activity records RATE_LIMITED_ENDPOINT. An email above the limit receives SMTP 451. For the details, see Endpoint Rate Limits.