Generate a forward signing secret

Generate a new signing secret for a forward action of a route. It is shown once; every forward POST is then signed with it so your endpoint can verify the sender.

Creates a fresh whsec_… secret for one forward action of the route and returns it once. It is stored sealed and never shown again — route responses only say has_secret: true. From the next delivery on, every forward POST carries Apifon-Signature and X-Apifon-Signature: the hex HMAC-SHA256 of the raw request body computed with this secret. Verify it before trusting the payload, exactly as you would a webhook signature.

POST /v3/routes/{id}/secret

Use this call to rotate a secret you may have leaked, or to add one to a forward action created without secret. The previous secret stops being used immediately, so update your endpoint first if it verifies strictly. To set a secret of your own choosing, pass secret on Create or Update an inbound route instead; secret: null on update removes it. Requires a `full_access` key. Limit: 30 calls per minute per key.

Path parameters

ParameterTypeRequiredDescription
iduuidRequiredThe route ID.

Body parameters

ParameterTypeRequiredDescription
urlstringOptionalThe forward URL whose secret to generate. Required when the route has several forward actions; may be omitted when it has one.

Responses

StatusDescription
201Created. { route_id, url, secret } — store secret now, it is never returned again.
400validation_error — the route has several forward actions and url is missing, or url is not one of them.
401Missing or invalid API key.
403insufficient_scope — requires a full_access key.
404No such route on your workspace.
409no_forward_action — the route has no forward action to secure.
429Rate limit exceeded (30 calls per minute).

Code examples

cURL
# One forward action on the route: no body needed
curl -X POST https://api.wemail.io/v3/routes/0b7e4c2d-9a1f-4e6b-8c3d-5f2a1b9e7d40/secret \
  -H "Authorization: Bearer afn_live_…" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://app.example.com/inbound"}'
# 201 {"route_id":"0b7e4c2d-9a1f-4e6b-8c3d-5f2a1b9e7d40","url":"https://app.example.com/inbound","secret":"whsec_…"}
Node.js
const res = await fetch("https://api.wemail.io/v3/routes/0b7e4c2d-9a1f-4e6b-8c3d-5f2a1b9e7d40/secret", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.WEMAIL_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://app.example.com/inbound" }),
});
const { secret } = await res.json();
// Store it now — it is never returned again. Verify forwards with:
//   crypto.createHmac("sha256", secret).update(rawBody).digest("hex") === req.headers["apifon-signature"]
Python
import os, requests

r = requests.post(
    "https://api.wemail.io/v3/routes/0b7e4c2d-9a1f-4e6b-8c3d-5f2a1b9e7d40/secret",
    headers={"Authorization": f"Bearer {os.environ['WEMAIL_API_KEY']}"},
    json={"url": "https://app.example.com/inbound"},
)
secret = r.json()["secret"]  # store it now — never returned again
# verify a forward: hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() == request.headers["Apifon-Signature"]
Go
client, _ := wemail.NewClient(os.Getenv("WEMAIL_API_KEY"))
ctx := context.WithValue(context.Background(), wemail.ContextAccessToken, os.Getenv("WEMAIL_API_KEY"))
out, _, err := client.API.RoutesAPI.RotateInboundRouteSecret(ctx, "0b7e4c2d-9a1f-4e6b-8c3d-5f2a1b9e7d40").Execute() // one forward action: no body
fmt.Println(out.Url, out.Secret) // store the secret now — never returned again
ResponseExample response
{
  "route_id": "0b7e4c2d-9a1f-4e6b-8c3d-5f2a1b9e7d40",
  "url": "https://app.example.com/inbound",
  "secret": "whsec_4f2a9c1e7b3d5a8e6c0f1b2d3e4a5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b"
}