← Back to documentation

Adding Authentication When Forwarding a Webhook

Configure inbound endpoint auth to validate senders and outbound webhook target auth to authenticate with destination systems.

8 min read

PayloadRelay supports authentication on both sides of the relay: inbound (who can send to your endpoint) and outbound (how PayloadRelay authenticates with your destination). This guide walks through configuring a fully authenticated webhook relay.

Purpose

This guide helps you:

  • Secure an endpoint with inbound authentication.
  • Configure outbound authentication on webhook targets.
  • Build an end-to-end authenticated relay between two services.
  • Choose the right auth type for your use case.

Prerequisites and permissions

  • A PayloadRelay account with endpoint and target edit access.
  • Credentials for your sending service (for inbound auth).
  • Credentials for your destination service (for outbound auth).

Step-by-step workflow

1. Understanding the two auth layers

Code Example
Sending Service ──auth──► PayloadRelay Endpoint ──auth──► Destination Service
                 (inbound)                        (outbound)
  • Inbound auth: validates that the sender is authorized to use your endpoint.
  • Outbound auth: authenticates PayloadRelay with the destination when forwarding.

Each layer is independent. You can use inbound auth only, outbound auth only, or both.

2. Configure inbound auth on the endpoint

Open the endpoint in EndpointsSecurity and choose an auth type:

Best for service-to-service communication and API integrations.

  1. Select Bearer token as the auth type.
  2. Enter a strong token value (e.g. generated with openssl rand -hex 32).
  3. Save.

Senders must include the token in every request:

Bearer token
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -H "Authorization: Bearer your-secret-token-here" \
  -H "Content-Type: application/json" \
  -d '{"event": "order.created", "order_id": "12345"}'

Best when you want a custom header name.

  1. Select API key header as the auth type.
  2. Set the header name (e.g. X-Api-Key).
  3. Enter the key value.
  4. Save.
API key header
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -H "X-Api-Key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{"event": "order.created", "order_id": "12345"}'

Best for simple integrations and tools that support HTTP Basic natively.

  1. Select Basic as the auth type.
  2. Enter username and password.
  3. Save.
Basic auth
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -u "username:password" \
  -H "Content-Type: application/json" \
  -d '{"event": "order.created", "order_id": "12345"}'

Requests without valid credentials receive a 401 response and an AUTH_FAILED outcome in Activity.

3. Configure outbound auth on the endpoint output

Open the endpoint in EndpointsTarget destinations and configure auth for the destination webhook target:

Bearer token (outbound)

  1. Edit the endpoint and select the Target destinations tab.
  2. Expand the webhook target's settings.
  3. Select Bearer as the auth type.
  4. Enter the destination's expected Bearer token.
  5. Save.

PayloadRelay adds Authorization: Bearer <token> to every forwarded request.

API key header (outbound)

  1. Edit the endpoint and expand the webhook target's settings under Target destinations.
  2. Select API key as the auth type.
  3. Set the header name the destination expects (e.g. X-Api-Key).
  4. Enter the key value.
  5. Save.

Basic auth (outbound)

  1. Edit the endpoint and expand the webhook target's settings under Target destinations.
  2. Select Basic as the auth type.
  3. Enter the username and password the destination expects.
  4. Save.

Custom headers (outbound)

For destinations that require additional headers beyond auth:

  1. Edit the endpoint and expand the webhook target's settings under Target destinations.
  2. Add custom headers (up to 25). Header values support template variables like {{originating_ip}} and {{uuid}}.
  3. Save.

Example: a destination requires both an API key and a tenant ID header:

  • Auth type: API key with header X-Api-Key
  • Custom header: X-Tenant-Id: acme-corp

Header forwarding

You can forward headers from the incoming request to the webhook target:

  • Forward all incoming headers: forwards all headers from the incoming request (restricted headers are always stripped).
  • Forward specific headers: specify individual header names to forward. If a header name doesn't exist in the incoming request, it is silently ignored.

Custom headers take priority over forwarded headers with the same name.

Restricted headers — the following headers are always stripped from forwarded headers, as they are controlled by the HTTP client or are security-sensitive:

Host, Connection, Content-Length, Transfer-Encoding, Upgrade, Proxy-Authorization, Proxy-Connection, TE, Trailer, Expect, Keep-Alive, HTTP2-Settings, Authorization, Cookie, Set-Cookie

4. SSL enforcement

For outbound webhook targets, enable Require valid SSL certificate to ensure PayloadRelay only delivers to destinations with valid TLS certificates. This prevents delivery to compromised or misconfigured endpoints.

5. End-to-end example: secure webhook relay

Scenario: Service A sends order events. You want to relay them to Service B with authentication on both sides.

Step 1: Create the webhook target for Service B

  1. Open Relay targetsAdd targetWebhook URL.
  2. Enter Service B's URL: https://api.service-b.com/webhooks/orders
  3. Save.

Step 2: Create the endpoint

  1. Open EndpointsCreate endpoint.
  2. Set method to POST, payload format to JSON.
  3. Under Security, set auth type to Bearer token with a token for Service A.
  4. Under Target destinations, attach the Service B webhook target.
  5. Configure outbound auth: set auth type to Bearer with Service B's token.
  6. Enable Require valid SSL certificate.
  7. Save and share the endpoint URL and token with Service A's team.

Step 3: Service A sends events

Code Example
# Service A sends to PayloadRelay
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
  -H "Authorization: Bearer service-a-token" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "order.created",
    "order_id": "ORD-98765",
    "customer": "[email protected]",
    "total": 149.99,
    "currency": "USD"
  }'

What happens:

  1. PayloadRelay validates Service A's Bearer token (inbound auth).
  2. Request is accepted for delivery.
  3. PayloadRelay forwards the payload to https://api.service-b.com/webhooks/orders with Service B's Bearer token (outbound auth).
  4. Both the inbound acceptance and outbound delivery are logged in Activity.

6. Auth type comparison

Auth TypeBest ForHeader Sent
Bearer tokenAPI-to-API, CI/CDAuthorization: Bearer <token>
API key headerCustom header name requirements<Header-Name>: <key>
Basic authLegacy systems, simple toolsAuthorization: Basic <base64>
NonePublic endpoints, testingNo auth header

7. Rotating credentials

When rotating auth credentials:

  1. Update the destination to accept both old and new credentials.
  2. Update the PayloadRelay endpoint or target with the new credential.
  3. Send a test to verify delivery succeeds.
  4. Remove the old credential from the destination.

This sequence avoids delivery failures during the rotation window.

Expected result and verification checks

  • Unauthenticated requests to the endpoint return 401 with AUTH_FAILED.
  • Properly authenticated requests return 200 with ACCEPTED.
  • Forwarded requests include the configured outbound auth headers.
  • Both inbound and outbound auth events are logged in Activity.

Common issues and fixes

  • AUTH_FAILED on inbound: double-check auth type and credential values match the endpoint configuration.
  • Outbound delivery failures: verify the destination's expected auth type and credentials on the webhook target.
  • SSL errors: if the destination has a self-signed certificate, temporarily disable Require valid SSL certificate for testing, then fix the certificate.
  • Custom header conflicts: custom header names cannot overlap with auth headers (e.g. you cannot add a custom Authorization header when Bearer auth is enabled).

Related guides