Set Flow endpoint destination (alias of PUT)
Identical to PUT on this resource, and handled by the same code. The resource has exactly one settable field, so “replace” and “merge” describe the same operation; answering 405 to whichever spelling the client guessed would be a trap with nothing behind it. See PUT /v1/flows/{id}/endpoint for the full contract.
curl --request PATCH \
--url https://pilotstatus.com.br/v1/flows/{id}/endpoint \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"url": "https://hooks.acme.com/flows/data-exchange"
}
'import requests
url = "https://pilotstatus.com.br/v1/flows/{id}/endpoint"
payload = { "url": "https://hooks.acme.com/flows/data-exchange" }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://hooks.acme.com/flows/data-exchange'})
};
fetch('https://pilotstatus.com.br/v1/flows/{id}/endpoint', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://pilotstatus.com.br/v1/flows/{id}/endpoint",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://hooks.acme.com/flows/data-exchange'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://pilotstatus.com.br/v1/flows/{id}/endpoint"
payload := strings.NewReader("{\n \"url\": \"https://hooks.acme.com/flows/data-exchange\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://pilotstatus.com.br/v1/flows/{id}/endpoint")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://hooks.acme.com/flows/data-exchange\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://pilotstatus.com.br/v1/flows/{id}/endpoint")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://hooks.acme.com/flows/data-exchange\"\n}"
response = http.request(request)
puts response.read_body{
"flowId": "cmf1a2b3c4d5e6f7g8h9i0j1",
"url": "https://hooks.acme.com/flows/data-exchange",
"hasSecret": true,
"endpointUri": "https://pilotstatus.com.br/api/flows/endpoint/AbC123.../1122334455",
"metaEndpointUri": "https://pilotstatus.com.br/api/flows/endpoint/AbC123.../1122334455",
"drift": false,
"numberHasKey": true,
"numberKeyUploadedAt": "2026-09-01T18:04:00.000Z",
"warnings": [],
"secret": "9f8a1c0e7b6d5a4c3e2f1b0a9d8c7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d"
}{
"error": "url é obrigatório: envie a URL https:// do seu webhook, ou `\"url\": null` para deixar este Flow sem destino.",
"errorEN": "url is required: send your webhook's https:// URL, or `\"url\": null` to leave this Flow with no destination.",
"code": "FLOW_ENDPOINT_URL_REQUIRED"
}{
"error": "Unauthorized"
}{
"error": "Tenant-scoped keys cannot call number endpoints",
"code": "TENANT_SCOPE_NOT_ALLOWED"
}{
"error": "Flow não encontrado para o número desta chave.",
"errorEN": "Flow not found for this key's number.",
"code": "FLOW_NOT_FOUND"
}{
"error": "Flows existem apenas em números Meta (API Oficial). O número desta chave não é Meta ou não tem uma WABA associada — use uma chave de um número Meta.",
"errorEN": "Flows only exist on Meta (Cloud API) numbers. This key's number is not a Meta number, or has no WABA behind it — use a key bound to a Meta number.",
"code": "FLOW_REQUIRES_META_NUMBER"
}{
"error": "Too many requests"
}{
"error": "Não foi possível guardar o segredo de assinatura deste endpoint: o serviço não está configurado para armazená-lo com segurança. Fale com o suporte.",
"errorEN": "Could not store this endpoint's signing secret: the service is not configured to keep it safely. Contact support.",
"code": "FLOW_ENDPOINT_SECRET_UNAVAILABLE"
}Authorizations
Your ps_ API key
Path Parameters
The local id of the Flow — the id field GET /v1/flows returns, never metaFlowId.
Body
The customer's own https:// webhook. null CLEARS the destination and keeps the signing secret. Required — omitting the field is 400 FLOW_ENDPOINT_URL_REQUIRED, never a wipe.
"https://hooks.acme.com/flows/data-exchange"
Mints a new HMAC signing secret and returns it once. Must be a real boolean — "true" is refused, never coerced (400 FLOW_ENDPOINT_ROTATE_INVALID).
false
Response
Destination stored. secret is present ONLY when this request minted one — a rotation, or the first save on this Flow
Was this page helpful?
curl --request PATCH \
--url https://pilotstatus.com.br/v1/flows/{id}/endpoint \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"url": "https://hooks.acme.com/flows/data-exchange"
}
'import requests
url = "https://pilotstatus.com.br/v1/flows/{id}/endpoint"
payload = { "url": "https://hooks.acme.com/flows/data-exchange" }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://hooks.acme.com/flows/data-exchange'})
};
fetch('https://pilotstatus.com.br/v1/flows/{id}/endpoint', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://pilotstatus.com.br/v1/flows/{id}/endpoint",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://hooks.acme.com/flows/data-exchange'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://pilotstatus.com.br/v1/flows/{id}/endpoint"
payload := strings.NewReader("{\n \"url\": \"https://hooks.acme.com/flows/data-exchange\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://pilotstatus.com.br/v1/flows/{id}/endpoint")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://hooks.acme.com/flows/data-exchange\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://pilotstatus.com.br/v1/flows/{id}/endpoint")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://hooks.acme.com/flows/data-exchange\"\n}"
response = http.request(request)
puts response.read_body{
"flowId": "cmf1a2b3c4d5e6f7g8h9i0j1",
"url": "https://hooks.acme.com/flows/data-exchange",
"hasSecret": true,
"endpointUri": "https://pilotstatus.com.br/api/flows/endpoint/AbC123.../1122334455",
"metaEndpointUri": "https://pilotstatus.com.br/api/flows/endpoint/AbC123.../1122334455",
"drift": false,
"numberHasKey": true,
"numberKeyUploadedAt": "2026-09-01T18:04:00.000Z",
"warnings": [],
"secret": "9f8a1c0e7b6d5a4c3e2f1b0a9d8c7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d"
}{
"error": "url é obrigatório: envie a URL https:// do seu webhook, ou `\"url\": null` para deixar este Flow sem destino.",
"errorEN": "url is required: send your webhook's https:// URL, or `\"url\": null` to leave this Flow with no destination.",
"code": "FLOW_ENDPOINT_URL_REQUIRED"
}{
"error": "Unauthorized"
}{
"error": "Tenant-scoped keys cannot call number endpoints",
"code": "TENANT_SCOPE_NOT_ALLOWED"
}{
"error": "Flow não encontrado para o número desta chave.",
"errorEN": "Flow not found for this key's number.",
"code": "FLOW_NOT_FOUND"
}{
"error": "Flows existem apenas em números Meta (API Oficial). O número desta chave não é Meta ou não tem uma WABA associada — use uma chave de um número Meta.",
"errorEN": "Flows only exist on Meta (Cloud API) numbers. This key's number is not a Meta number, or has no WABA behind it — use a key bound to a Meta number.",
"code": "FLOW_REQUIRES_META_NUMBER"
}{
"error": "Too many requests"
}{
"error": "Não foi possível guardar o segredo de assinatura deste endpoint: o serviço não está configurado para armazená-lo com segurança. Fale com o suporte.",
"errorEN": "Could not store this endpoint's signing secret: the service is not configured to keep it safely. Contact support.",
"code": "FLOW_ENDPOINT_SECRET_UNAVAILABLE"
}