Skip to main content
Any system can send things to Brein through one door: your backend, a no-code tool or an agent. Each request is a CloudEvent 1.0 signed with Standard Webhooks 1.0.0. Brein stores it exactly as it arrived, applies it to your CRM and keeps a trail of everything that happened.

1. Create a Source

A Source is where things enter Brein. Create one in Settings → Integrations. Only the workspace owner or an admin can. When you create it you get two things:
  • The address you send to: https://api.trybrein.com/api/v1/door/<source id>.
  • The secret, whsec_ followed by base64. It is shown once. Keep it in your secrets manager; never in a browser or a repository.
If you want each Arrival to also open an Opportunity, pick the Pipeline and stage when you create it. You can change it later.

2. Build the event

The body is a CloudEvent 1.0 in JSON, up to 256 KiB.
data does carry email and phone: that is what identifies the person. The events Brein writes afterwards never carry them.

3. Sign it and send it

Sign webhook-id, webhook-timestamp and the body, byte for byte as you send it, with HMAC-SHA256. The key is the secret without whsec_, base64-decoded.
Any Standard Webhooks library signs the same way. When you retry, reuse the same webhook-id: Brein recognizes it and duplicates nothing.

4. Read the response

A 401 never reveals whether the Source exists. For 24 hours after you rotate the secret, Brein accepts signatures from both the new and the previous one, so you can rotate without downtime.

5. What happens next

Each request becomes an Arrival with its trail. See them on their Integration’s page, in Settings → Integrations, or with the arrival_read tool from your agent. Nothing is lost silently: every request ends in one of those states, and each step is in the event ledger.

webhook Sources

Besides the signed contract above, a Source can be of type webhook: it receives any tool’s notice as that tool sends it, with no CloudEvent, and a mapping that a person confirms says what each field is. This is what Integrations use. Create one with POST https://api.trybrein.com/api/v1/workspaces/<slug>/door/sources, with type: "webhook" and, optionally, a template (calcom, calendly, stripe, tally, typeform, jotform, webflow, shopify, hotmart, clerk or posthog). How it is verified depends on the Source: The body can be JSON, application/x-www-form-urlencoded or multipart/form-data, up to 256 KiB. A signature or token that does not match gives 401, the same as a Source that does not exist. Responses are those of the table above, with these differences:
  • 202 or 200 with { "arrival": "<id>", "status": "unmapped" } when the Source has no mapping yet: the notice is stored as the example.
  • 200 with { "ignored": true, "reason": "unsupported_event" } when the notice’s type is not one the mapping accepts. No Arrival is created.
  • A notice with a list of people (a batch) answers { "arrivals": [ { "arrival", "status", "duplicate" } ], "ignored": <number> }, with one Arrival per element.
  • A duplicate is recognized by the notice id the mapping points to, or by a fingerprint of its content.
To read a Source with its example and its mapping proposal, confirm the mapping and reprocess, all inside your workspace and with your session: The raw notice and the example are deleted after 30 days; without them there is nothing to reprocess (expired).

Test without risk

A test workspace copies your workspace’s structure (Pipelines, Forms and Sources) without your data or members. In it, no credits are spent, no email is sent, no provider is called and nothing is delivered to a Destination. The owner or an admin creates one with POST https://api.trybrein.com/api/v1/workspaces/<slug>/sandboxes; up to five per workspace. The response carries its Sources’ new secrets, once. Inside a test workspace you can send a sample Arrival to any Source without signing anything, with the arrival_send_test tool or with POST …/workspaces/<slug>/door/sources/<id>/test-arrivals and { "type": "contact.created" }.