NeboAI · how to

Create a webhook

Give an outside system a way to start a run: a form, a CRM event, anything that can POST.

TimeFifteen minutes
Whereneboai.com/app

Mint the key

In the web console, open Settings → Webhooks and create an endpoint. Bind it to the employee that should handle the payload. If you want it to fire one specific workflow rather than starting a general run, bind the workflow name too.

You get back two things: an endpoint id, and a key beginning nbwh_. The key is the credential. The id is only a stable URL segment, so treat the key the way you would treat a payment secret and the id as public.

Call it

curl -X POST https://api.neboai.com/api/v1/hooks/$ENDPOINT_ID \ -H "Authorization: Bearer nbwh_..." \ -H "Content-Type: application/json" \ -d '{"name":"Dana Whitfield","email":"dana@acme.com","message":"Do you do commercial work?"}'

A successful call returns:

{"delivered": true}

The payload lands in that employee's space and starts a run. Test by hand before wiring anything to it.

ResponseMeans
202Delivered.
404The id in the URL is not the one the key is bound to. Reported as not-found on purpose, so it never confirms whether an id exists.
401Key missing, malformed, or revoked.
413Body over 256 KB. Send fields, not attachments.
429Over 60 requests a minute on this endpoint.

Wire it to something

Post from your server, never from the browser. A key in client-side code is a key anyone can read and use to fire your employee at will.

// server-side handler await fetch(`https://api.neboai.com/api/v1/hooks/${process.env.NEBO_HOOK_ID}`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.NEBO_HOOK_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ name, email, message, source: 'pricing-page' }) });

Add a source field naming where it came from. It costs nothing and turns "we got 40 leads" into knowing which page produced them.

Why this is safe to expose

The origin clamp

The delivered envelope is stamped as having arrived over webhook, and the tool policy governs what a run from that origin may do. A payload from a public form cannot talk its way into a shell, whatever it contains. That is enforcement in code rather than an instruction in a prompt, so it holds even against a message written specifically to manipulate the employee.

It is still worth scoping the employee narrowly. The clamp stops a category of attack; it does not decide whether this particular employee should be able to send mail or move money. That is what the approval controls are for.

When it goes wrong

404 on a key you just made

The endpoint id in the URL must be the one the key is bound to. Copy both from the same row.

Delivered, but nothing happens

The payload arrived and the employee decided there was nothing to do. Check what the run did, and make the instruction explicit about acting on every payload.

429 under normal load

Sixty a minute is per endpoint. If one form legitimately exceeds that, mint a second endpoint rather than retrying into the limit.