Sending Data to an Endpoint
Use code examples to send a `POST` request to a PayloadRelay endpoint.
An endpoint is a public HTTPS URL that accepts an HTTP request and sends it to your configured targets. This guide shows how to send data from different languages and environments. The examples use POST with the JSON payload format. For an endpoint that exists, use the code samples on its edit page. Those samples use the current method, payload format, query parameters, authentication, HMAC, captcha, and required-header configuration. Save your changes before you send a generated sample.
Endpoint URL format#
https://api.payloadrelay.com/relay/<endpoint-id>The exact URL appears on the endpoint edit page. Copy the URL from that page.
An HTTP 202 Accepted response means that PayloadRelay accepted the event. It does not mean that each destination delivered it. Activity shows Pending during the delivery. Activity shows a final outcome when the delivery attempts stop. An accepted event with no enabled destination completes, and PayloadRelay makes no delivery.
A temporary failure can return HTTP 503 with Retry-After. The event does not use quota, but a delivery can still occur. Wait for the given delay, then send the original request again. PayloadRelay can deliver an event more than once. Use a stable event key. Before you send the request again, make the receiver safe for the same event more than once.
The generic endpoint_unavailable response does not show the cause. The endpoint can be paused, blocked by billing, or stopped by an operator configuration failure. An organization administrator can find the cause in the authenticated endpoint configuration, in Activity, and in Billing. The delivery_queue_unavailable response also warns that PayloadRelay can deliver the event more than once.
PayloadRelay keeps a metadata-only Activity trail and the delivery outcomes for 30 days. PayloadRelay does not store a customer relay request body or a customer message body in its databases, activity logs, object storage, or backups. A body stays only in memory and in the delivery, retry, and dead-letter queues. It stays there only while PayloadRelay delivers the event. If the delivery fails permanently, the message stays in a dead-letter queue for a maximum of 7 days for diagnosis or a new delivery. PayloadRelay can keep operational metadata, such as an SMTP envelope sender address, in the 30-day Activity trail.
Authentication#
Each endpoint can use one of these inbound authentication modes:
| Authentication type | What to send |
|---|---|
NONE | No authentication header required |
BASIC | Authorization: Basic <base64(USERNAME:PASSWORD)> |
BEARER | Authorization: Bearer YOUR_TOKEN |
API_KEY | <configured-header-name>: YOUR_API_KEY |
HMAC | Provider or custom signature headers. See HMAC Inbound Verification |
If the endpoint requires specific headers, include them in every request.
curl#
No authentication#
curl -X POST \
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID' \
-H 'Content-Type: application/json' \
-d '{"event":"test","timestamp":"2024-01-01T00:00:00Z","data":{"id":123}}'Bearer authentication#
curl -X POST \
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{"event":"test","timestamp":"2024-01-01T00:00:00Z","data":{"id":123}}'With a required header#
curl -X POST \
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'X-Tenant-Id: acme-corp' \
-d '{"event":"test","timestamp":"2024-01-01T00:00:00Z","data":{"id":123}}'Form-urlencoded#
curl -X POST \
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'event=test&id=123'File uploads and multipart form data#
A relay endpoint does not accept multipart/form-data or a file upload.
Use JSON or application/x-www-form-urlencoded fields for the metadata. You can
also upload the file to object storage, and send its URL to the endpoint.
Node.js (fetch)#
No authentication#
const response = await fetch('https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: 'test', timestamp: '2024-01-01T00:00:00Z', data: { id: 123 } }),
});
const result = await response.json();
console.log(result);Bearer authentication#
const response = await fetch('https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN',
},
body: JSON.stringify({ event: 'test', timestamp: '2024-01-01T00:00:00Z', data: { id: 123 } }),
});With a required header#
const response = await fetch('https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN',
'X-Tenant-Id': 'acme-corp',
},
body: JSON.stringify({ event: 'test', timestamp: '2024-01-01T00:00:00Z', data: { id: 123 } }),
});Python (requests)#
No authentication#
import requests
response = requests.post(
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID',
json={'event': 'test', 'timestamp': '2024-01-01T00:00:00Z', 'data': {'id': 123}},
)
print(response.status_code, response.json())Bearer authentication#
import requests
headers = {
'Authorization': 'Bearer YOUR_TOKEN',
}
response = requests.post(
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID',
json={'event': 'test', 'timestamp': '2024-01-01T00:00:00Z', 'data': {'id': 123}},
headers=headers,
)With a required header#
headers = {
'Authorization': 'Bearer YOUR_TOKEN',
'X-Tenant-Id': 'acme-corp',
}
response = requests.post(url, json=payload, headers=headers)Go (net/http)#
No authentication#
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
payload := map[string]interface{}{
"event": "test",
"timestamp": "2024-01-01T00:00:00Z",
"data": map[string]int{"id": 123},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
}Bearer authentication#
req.Header.Set("Authorization", "Bearer YOUR_TOKEN")With a required header#
req.Header.Set("X-Tenant-Id", "acme-corp")PHP (curl)#
No authentication#
<?php
$ch = curl_init('https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'event' => 'test',
'timestamp' => '2024-01-01T00:00:00Z',
'data' => ['id' => 123],
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;Bearer authentication#
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer YOUR_TOKEN',
]);With a required header#
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer YOUR_TOKEN',
'X-Tenant-Id: acme-corp',
]);Ruby (Net::HTTP)#
No authentication#
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request['Content-Type'] = 'application/json'
request.body = { event: 'test', timestamp: '2024-01-01T00:00:00Z', data: { id: 123 } }.to_json
response = http.request(request)
puts "Status: #{response.code}"
puts response.bodyBearer authentication#
request['Authorization'] = 'Bearer YOUR_TOKEN'With a required header#
request['X-Tenant-Id'] = 'acme-corp'C# (HttpClient)#
No authentication#
using System.Net.Http;
using System.Net.Http.Json;
var client = new HttpClient();
var payload = new { @event = "test", timestamp = "2024-01-01T00:00:00Z", data = new { id = 123 } };
var response = await client.PostAsJsonAsync("https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID", payload);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Status: {(int)response.StatusCode}");
Console.WriteLine(body);Bearer authentication#
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_TOKEN");With a required header#
client.DefaultRequestHeaders.Add("X-Tenant-Id", "acme-corp");Java (HttpClient, Java 11+)#
No authentication#
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
String body = "{\"event\":\"test\",\"timestamp\":\"2024-01-01T00:00:00Z\",\"data\":{\"id\":123}}";
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"))
.POST(HttpRequest.BodyPublishers.ofString(body))
.header("Content-Type", "application/json")
.build();
var client = HttpClient.newHttpClient();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println(response.body());
}
}Bearer authentication#
.header("Authorization", "Bearer YOUR_TOKEN")With a required header#
.header("X-Tenant-Id", "acme-corp")GitHub Actions#
Use this example to send an event from a GitHub Actions workflow, for example, after a deployment.
No authentication#
- name: Send event to PayloadRelay
run: |
curl -X POST \
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID' \
-H 'Content-Type: application/json' \
-d '{"event":"deploy","ref":"${{ github.ref }}","sha":"${{ github.sha }}"}'Bearer authentication#
- name: Send event to PayloadRelay
env:
RELAY_TOKEN: ${{ secrets.RELAY_TOKEN }}
run: |
curl -X POST \
'https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $RELAY_TOKEN" \
-d '{"event":"deploy","ref":"${{ github.ref }}","sha":"${{ github.sha }}"}'Store your token as a GitHub Actions secret. Do not hard-code the token in the workflow file.
With a required header#
-H 'X-Tenant-Id: acme-corp' \Live code samples in the app#
When you open the edit page of an endpoint in the PayloadRelay dashboard, the Send to this endpoint — code samples panel appears on the page. The panel:
- Fills in the relay URL.
- Fills in the authentication headers for the endpoint authentication type.
- Includes each required header that you define.
- Changes when you change the authentication type or the required headers in the editor.
- Gives a
Copybutton on each tab.
Next steps#
- See Endpoint Management to configure authentication, required headers, and payload format.
- See Observability to monitor delivery outcomes in Activity.
- If a request fails, see Troubleshooting Ingest.