Webhooks

$envless->webhooks->create()

Register an endpoint and subscribe it to events

php
/**
 * @param WebhookCreate $body
 * @return CreatedWebhookResource
 */
public function create(array $body, int|float|null $timeout = null): array

Registers an HTTPS receiver and subscribes it to a set of events. The endpoint is created with enabled set to true, so any matching event emitted after this call is queued for it straight away. The delivery worker drains the queue on a 5 second tick, so the first request usually lands a moment after this call returns.

This response is the only place the API hands you the full secret. Every read gives you secretLastFour instead, so persist the secret before you do anything else. If you lose it you have two ways back: reveal it in the dashboard, which needs the webhooks:secret_read permission plus a step up verification, or call rotateSecret from here. Rotation is immediate and there is no overlap window, because each delivery is signed at send time from the endpoint's current secret, so queued deliveries and retries switch to the new secret too. The secret is formatted ev_whsec_ followed by base64url of 24 random bytes, and the HMAC key is the full string including that prefix: do not strip it, and if a verification library wants a base64 secret pass base64(utf8(secret)).

url is validated hard. It must be https, at most 2048 characters, free of embedded credentials, and pointed at a publicly routable host, which rules out loopback, private and carrier grade NAT ranges, link local and unique local IPv6, localhost, cloud metadata hosts and anything ending .internal, .local, .localdomain or .home.arpa. The host is checked again at delivery time: it is resolved and the attempt fails if any resolved address is private. Redirects are never followed, so a 3xx from your receiver is recorded as a failed attempt: register the final URL. eventTypes must be non empty and drawn from listEventTypes, and a 400 request.body_invalid names each offending value.

Example

php
use Envless\Envless;

$envless = new Envless();

$created = $envless->webhooks->create([
    'name' => 'production sync',
    'url' => 'https://hooks.example.com/envless',
    'eventTypes' => ['variable.created', 'variable.updated'],
]);

echo $created['secret'], PHP_EOL;
echo "{$created['id']} {$created['secretLastFour']}", PHP_EOL;

Parameters

ParameterTypeRequiredDescription
$bodyWebhookCreateYesThe fields below, as one array.
$body['name']stringYesLabel shown in the dashboard and matched by list search, at most 64 characters.
$body['url']stringYesThe https receiver URL, publicly routable and with no credentials in it.
$body['eventTypes']list<string>YesNon empty list of event names taken from listEventTypes.
$body['description']stringNoFree text note, at most 200 characters.
$timeoutint|floatNoSeconds each attempt of this call may take, the response body included, before it throws Envless\Exception\NetworkException with isTimeout() true. Overrides the client's timeout for this call, and 0 turns the limit off.

Returns

CreatedWebhookResource, a WebhookResource plus the plaintext secret. Alongside it you get id, name, url, description, eventTypes, enabled, secretLastFour, lastSuccessAt, lastFailureAt, createdAt and updatedAt.

Worth knowing

  • Verify every incoming request with Envless::verifyWebhookSignature() from the package root: it checks the HMAC over id, timestamp and body plus the timestamp drift, then returns the parsed event.
  • Delivery is at least once with up to 5 attempts, retrying 30s, 2m, 10m then 30m after the failed attempt, and a 10 second request timeout, so make the handler idempotent on the webhook-id header.
  • A workspace is capped at 20 endpoints, and creating the 21st is a 409 request.conflict. The separate 500 queued deliveries ceiling is enforced on redeliver, not on normal fan out.
  • An API key restricted to specific projects cannot call this at all: webhooks are workspace wide, so a project locked key gets 403 auth.key_project_restricted.

Required scopes

webhooks:write

Underlying endpoint

POST /webhooks

Request and response schema, every error code, and a live playground.

In TypeScript

envless.webhooks.create()

The same method in @goenvless/sdk, with the same request, retries and errors.