# Connect using a WebHook

**Humanic's webhook endpoint accepts any HTTP `POST` request carrying a JSON payload.** If your product, database, or automation tool can make an HTTP call, it can send data to Humanic — no native integration required.

This is how you connect tools that don't have a dedicated Humanic integration: custom backends, internal dashboards, no-code platforms like Make or Zapier, form builders, CRMs, payment processors, or any in-house system you've built.

***

### When to use a webhook connection

Use a webhook when you want to:

* Send a user event from your own backend the moment it happens (signup, upgrade, cancellation, feature trigger)
* Connect a tool that doesn't have a built-in Humanic integration
* Push data from a no-code automation (Zapier, Make, n8n) into Humanic
* Trigger a campaign from a form submission, payment event, or CRM status change
* Pipe events from a custom analytics stack directly into Humanic

If your tool is PostHog, Shopify, Amplitude, Segment, or Stripe — those have dedicated integration guides. Use this page for everything else.

***

### How it works

```
Your system / tool / product backend
         ↓
HTTP POST to Humanic webhook URL
  (JSON payload with email + event data)
         ↓
Humanic receives and parses the payload
         ↓
Humanic matches or creates a contact
         ↓
Campaign triggers based on the event
         ↓
Email sends from your configured domain
```

Every webhook call you send is a signal. Humanic uses that signal to decide who to email, when, and with what content.

***

### Step 1 — Get your webhook URL

1. In Humanic, go to **Integrations → Webhooks**
2. Click **Create Webhook** (or copy the existing URL if one is already generated)
3. Copy the endpoint URL — it will look like:

```
https://api.humanic.ai/webhooks/inbound/[your-unique-id]
```

Keep this URL private. Anyone with it can POST data to your Humanic workspace.

***

### Step 2 — Structure your JSON payload

Humanic expects a `POST` request with `Content-Type: application/json`. The minimum required field is `email`. Everything else is optional but directly useful for personalisation and campaign targeting.

#### Minimum valid payload

json

```json
{
  "email": "user@example.com"
}
```

This creates or updates a contact. Without an event name, no campaign is triggered — the contact is just added to your list.

#### Recommended payload — contact + event

json

```json
{
  "email": "user@example.com",
  "event": "user_signed_up",
  "data": {
    "name": "Alex Rivera",
    "plan": "free",
    "company": "Acme Inc",
    "signup_source": "landing_page"
  }
}
```

#### Full payload with all supported fields

json

```json
{
  "email": "user@example.com",
  "event": "checkout_completed",
  "userId": "usr_8a3f2d",
  "data": {
    "name": "Alex Rivera",
    "first_name": "Alex",
    "last_name": "Rivera",
    "plan": "pro",
    "company": "Acme Inc",
    "company_size": "11-50",
    "country": "US",
    "order_value": "149.00",
    "product_name": "Pro Plan - Annual",
    "custom_variable_1": "any value you want available in email copy"
  }
}
```

#### Field reference

| Field             | Type   | Required    | Description                                                                                          |
| ----------------- | ------ | ----------- | ---------------------------------------------------------------------------------------------------- |
| `email`           | string | ✅ Yes       | The contact's email address. Used to match or create a contact.                                      |
| `event`           | string | Recommended | The event name that triggers a campaign. Must match a campaign trigger you've configured in Humanic. |
| `userId`          | string | Optional    | Your internal user ID. Used to deduplicate contacts across sessions.                                 |
| `data.name`       | string | Optional    | Full name for personalisation                                                                        |
| `data.first_name` | string | Optional    | Used in `{{first_name}}` personalisation token                                                       |
| `data.*`          | any    | Optional    | Any key-value pair. All `data` fields become available as `{{variable}}` tokens in your email copy.  |

***

### Step 3 — Send a test call

Before wiring this into production, verify the connection manually using cURL, Postman, or any HTTP client.

**cURL example:**

bash

```bash
curl -X POST https://api.humanic.ai/webhooks/inbound/[your-unique-id] \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@yourdomain.com",
    "event": "user_signed_up",
    "data": {
      "name": "Test User",
      "plan": "free"
    }
  }'
```

A successful call returns `HTTP 200`. Go to **Integrations → Webhooks → Event Log** in Humanic to confirm the event appeared with the correct fields.

***

### Step 4 — Map events to campaigns

Receiving an event in Humanic doesn't automatically send an email. You need a campaign with a matching trigger.

1. Go to **Campaigns → Create Campaign**
2. Set the trigger to **Webhook Event**
3. Enter the exact event name you're sending (e.g., `user_signed_up`)
4. Build your email sequence and activate

From now on, every time Humanic receives that event for a contact, it fires the campaign.

> 💡 Event names are case-sensitive. `User_Signed_Up` and `user_signed_up` are treated as different events. Stick to lowercase with underscores.

***

### Sending from common tools

#### Zapier

In a Zap, add a **Webhooks by Zapier** action step. Choose **POST** as the method, paste your Humanic webhook URL, set **Data Pass-Through** to `false`, and build your JSON payload in the **Data** section.

#### Make (formerly Integromat)

Add an **HTTP → Make a Request** module. Set method to `POST`, paste the Humanic URL, set the body type to `Raw` with `Content-Type: application/json`, and write your JSON in the body field. Use Make's dynamic variables to pull in values from upstream modules.

#### n8n

Use the **HTTP Request** node. Method: `POST`. URL: your Humanic webhook URL. Body Content Type: `JSON`. Build the body using n8n's expression editor to map fields from your trigger node.

#### Your own backend (Node.js example)

javascript

```javascript
await fetch('https://api.humanic.ai/webhooks/inbound/[your-id]', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: user.email,
    event: 'subscription_upgraded',
    data: {
      name: user.name,
      plan: newPlan,
      upgraded_at: new Date().toISOString()
    }
  })
});
```

***

### Best practices

**Always include `email`.** Without it, Humanic can't associate the event with a contact and the payload is discarded.

**Use consistent event names.** Decide on a naming convention before you start — `snake_case` is the most common standard. Don't mix `user_signup`, `UserSignup`, and `signup_complete` for the same action.

**Keep `data` fields clean and predictable.** Every key you include in `data` becomes a personalisation variable in Humanic. If you send `data.plan = "pro"`, you can use `{{plan}}` in your email copy. Only include fields you'll actually use.

**Return `200` fast.** If you're building your own receiver and then forwarding to Humanic, respond to upstream services immediately and process async. Long response times can cause upstream tools to retry, resulting in duplicate events.

**Use a staging workspace for testing.** Connect your staging/development environment to a test Humanic workspace. Never use production webhook URLs for load testing.

***

### Troubleshooting

#### Events aren't appearing in Humanic

Check that your request is hitting the correct URL and that your `Content-Type` header is `application/json`. An incorrectly formatted body or wrong content type will result in a silent failure on some tools. Send a raw cURL request to isolate whether the issue is with the payload or with your tool's configuration.

#### Contact is created but no email sends

The `event` name in your payload doesn't match any campaign trigger in Humanic. Go to your campaign settings and confirm the trigger event name matches exactly — including case — what you're sending.

#### Duplicate contacts appearing

This happens when the same email arrives under multiple variations (e.g., `User@Example.com` and `user@example.com`). Humanic normalises emails to lowercase, but if your source system sends inconsistent values, deduplicate before sending.

#### `data` fields not appearing in emails

Check that the field names in your `data` object match the tokens you've used in your email template. If you send `data.first_name` but use `{{firstName}}` in your template, the substitution won't work. Match the format exactly.

***

### Frequently Asked Questions

**Is the webhook URL authenticated?** The URL itself acts as a secret — it's unique and unguessable. Don't share it publicly or commit it to a public repository. If you suspect it's been compromised, regenerate it in **Integrations → Webhooks**.

**Does Humanic retry failed deliveries?** Humanic expects your source system to handle retries. If a payload fails to process (e.g., missing required fields), it won't be retried automatically. Build retry logic on your sending side if reliability is critical.

**Can I send multiple events in a single request?** No. Each webhook call should contain one event for one contact. For bulk historical imports, use CSV import instead.

**Can I use the same webhook URL for multiple event types?** Yes. One URL handles all event types. The `event` field in the payload determines which campaign fires.

**What HTTP response should I expect?** A successful payload returns `HTTP 200 OK`. A `400` response means your payload is malformed or missing required fields. A `5xx` means a temporary issue on Humanic's end — retry with exponential backoff.

***

Want to be notified when Cl
