← Back to documentation

Sending Data to an Endpoint

Use code examples to send a `POST` request to a PayloadRelay endpoint.

4 min read

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#

Code Example
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 typeWhat to send
NONENo authentication header required
BASICAuthorization: Basic <base64(USERNAME:PASSWORD)>
BEARERAuthorization: Bearer YOUR_TOKEN
API_KEY<configured-header-name>: YOUR_API_KEY
HMACProvider or custom signature headers. See HMAC Inbound Verification

If the endpoint requires specific headers, include them in every request.


curl#

No authentication#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
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#

Code Example
headers = {
    'Authorization': 'Bearer YOUR_TOKEN',
    'X-Tenant-Id': 'acme-corp',
}
response = requests.post(url, json=payload, headers=headers)

Go (net/http)#

No authentication#

Code Example
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#

Code Example
req.Header.Set("Authorization", "Bearer YOUR_TOKEN")

With a required header#

Code Example
req.Header.Set("X-Tenant-Id", "acme-corp")

PHP (curl)#

No authentication#

Code Example
<?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#

Code Example
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer YOUR_TOKEN',
]);

With a required header#

Code Example
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer YOUR_TOKEN',
    'X-Tenant-Id: acme-corp',
]);

Ruby (Net::HTTP)#

No authentication#

Code Example
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.body

Bearer authentication#

Code Example
request['Authorization'] = 'Bearer YOUR_TOKEN'

With a required header#

Code Example
request['X-Tenant-Id'] = 'acme-corp'

C# (HttpClient)#

No authentication#

Code Example
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#

Code Example
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_TOKEN");

With a required header#

Code Example
client.DefaultRequestHeaders.Add("X-Tenant-Id", "acme-corp");

Java (HttpClient, Java 11+)#

No authentication#

Code Example
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#

Code Example
.header("Authorization", "Bearer YOUR_TOKEN")

With a required header#

Code Example
.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#

Code Example
- 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#

Code Example
- 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#

Code Example
-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 Copy button on each tab.

Next steps#