> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oncortex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Receiving webhooks

> Let an outside tool push content into a brain

<Info>
  This is a technical reference for developers wiring up other tools. For everyday use, see [other sources](/capture/other-sources).
</Info>

A webhook source lets any tool that can send an HTTP request push content into a brain. You create the source on the brain, and the tool sends new items to it. Cortex authenticates each delivery, optionally checks it against guard rules, and drops it into the inbox.

## Setting up

Open the brain's **Settings** page and choose **Ingest sources** (you need to be an Admin or Owner of the brain). This is not the Sources page in the brain's side navigation, which is the archive of items that have already arrived; the settings block manages the senders.

1. Click **New source** and give it a label, such as the name of the tool that will send.
2. Choose how deliveries will be authenticated. This cannot be changed later:
   * **Shared secret:** Cortex gives you a secret; the sender includes it in a header. Simplest to set up.
   * **Signature (HMAC):** the sender signs each request body with the secret. More secure, and the right choice if the sending tool supports it.
3. Optionally add guard rules (allowed content types, a size cap, allowed sender domains), a target folder, a client to pin the source to on a [partitioned brain](/brains/partitions), and a default filing skill.
4. Click **Create source**. Cortex shows the secret **once**, with the delivery URL, the headers to send and a ready-made `curl` example. Copy the secret now; it is stored encrypted and never shown again. If you lose it, delete the source and create another.

The list shows every source with its guard, folder, client pin, default skill and delivery URL. **Edit** changes everything except the kind, authentication mode and secret. **Delete** asks you to type the source's label, revokes the secret at once, and leaves the items the source already delivered untouched.

## Sending a delivery

Post the content as the raw request body to the brain's ingest endpoint:

```
POST https://api.oncortex.ai/api/ingest/{brainId}
```

You can add `?path=some/folder` to suggest where the content should file. It is recorded as a hint for the filing pass, not an order, and the payload itself can never choose its own destination. A source can also carry a standing target folder in its settings; the per-delivery `path` wins when both are present.

Headers:

| Header                      | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Ingest-Secret`           | The shared secret (shared-secret mode).                                                                                                                                                                                                                                                                                                                                                                                                   |
| `X-Cortex-Signature`        | `sha256=<hex>`, the HMAC of the raw body (signature mode).                                                                                                                                                                                                                                                                                                                                                                                |
| `X-Filename`                | A name for the item.                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `X-Ingest-External-Id`      | Optional. A stable id so re-delivery does not duplicate.                                                                                                                                                                                                                                                                                                                                                                                  |
| `X-Ingest-Senders`          | Optional. Comma-separated sender addresses, for guard rules and, in a partitioned brain, for deciding the client by domain.                                                                                                                                                                                                                                                                                                               |
| `X-Ingest-Canonical-Url`    | Optional. Where the document lives (an absolute http or https link). Kept on the source record beside the copy that was received.                                                                                                                                                                                                                                                                                                         |
| `X-Ingest-Provider`         | Optional. `sharepoint`, `onedrive`, `gdrive`, `confluence`, `notion` or a name of your own; inferred from the link when omitted.                                                                                                                                                                                                                                                                                                          |
| `X-Ingest-Provider-Item-Id` | Optional. The stable id at the provider. With the version, it identifies revisions of one document.                                                                                                                                                                                                                                                                                                                                       |
| `X-Ingest-Version`          | Optional. The etag or version at delivery. A new version of a known document becomes a new item linked to the earlier one; the same version again is a repeat.                                                                                                                                                                                                                                                                            |
| `X-Ingest-Partition`        | Optional. The client (or site, or matter) key in a [partitioned brain](/brains/partitions); `?partition=` on the address does the same. Unknown or archived keys are refused. A source can also be pinned to one partition in its settings.                                                                                                                                                                                               |
| `X-Ingest-Skill`            | Optional. Pins the filing skill (`ingest`, `ingest-meeting`, `ingest-doc` or `ingest-conversation`); `?skill=` on the address does the same. The automatic filer then skips its "is this worth filing" check for the delivery and runs that skill. A source can carry a standing default skill in its settings; the per-delivery header wins. A name that is not a skill is refused with a 400 listing the skills, and nothing is stored. |

```bash theme={null}
curl https://api.oncortex.ai/api/ingest/{brainId} \
  -H "X-Ingest-Secret: your-source-secret" \
  -H "X-Filename: form-submission.md" \
  -H "X-Ingest-External-Id: submission-4821" \
  --data-binary @payload.txt
```

## Guard rules

A source can carry guard rules, set when you create it or from **Edit**, that decide which deliveries to accept, for example only from certain senders. A delivery that fails the guard is rejected outright and never stored: nothing that does not match your rules gets into the brain. This keeps a public-facing webhook from becoming a way to dump arbitrary content into your knowledge.

## Idempotency

Set `X-Ingest-External-Id` to a stable value per item. If the same id arrives twice, Cortex recognises the repeat and does not create a second inbox item, so a tool that retries deliveries stays safe. When you send the reference headers and no external id, Cortex derives one from them (`{provider}:{itemId}@{version}`), which is what makes a document's updates arrive as linked revisions: a Power Automate flow on a SharePoint library needs nothing more than the drive item id and the etag in those headers.
