Memory API
Webhooks
Send events from an issue tracker, a CRM, a chat tool or your own application into Harny as data points, and check the signature on the webhooks Harny sends to you.
Copy page
To check that a webhook came from Harny, go to Check that an event came from Harny.
Send events from another system
Send events with POST /v1/memory/ingest. Each event becomes one data point. Map the event to the ingest body in your own code: the text of the event goes in content, the time it happened in timestamp, and your id for the event in id. A repeated id replaces the earlier data point.
curl -X POST https://api.harny.ai/v1/memory/ingest \
-H "Authorization: Bearer $HARNY_APP_KEY" \
-H "X-Harny-User: demo-user" \
-H "Content-Type: application/json" \
-d '{ "id": "issue-4412",
"content": "Acme asked to move the pilot review to Friday.",
"label": "Issue 4412",
"timestamp": "2026-07-28T16:00:00Z" }'A stored event answers 202 with the ingestionId, the sourceId and status: "queued". The other fields of the event go in metadata, and recall returns them in sources[].metadata.
An event is not metered on its own. A person counts toward your monthly-active end users when they use your app. Pricing explains the meter. Sending data covers batches and idempotency.
Check that an event came from Harny
When you add a webhook to an app in the console, Harny shows its signing secret once. Save it then. Harny calls your address with a POST and signs each call, so your server can tell a real call from a forged one.
| Header | What it holds |
|---|---|
X-Harny-Signature | sha256= followed by the HMAC-SHA256 of the raw request body, written in hex and keyed with the signing secret. |
X-Harny-Event-Type | The event, for example scenario.complete. |
X-Harny-Event-Id | One id per event. A retry of the same event carries the same id, so you can ignore one you have already handled. |
X-Harny-Delivery-Id | One id per delivery attempt. |
Compute the signature over the body exactly as received, before you parse it, and compare it with the header in constant time:
import hashlib, hmac
def is_from_harny(secret: str, raw_body: bytes, header: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)Answer with any 2xx status within 10 seconds to confirm. If your address fails or times out, Harny tries again after 1 minute, 5 minutes, 25 minutes and 2 hours, five attempts in all. The console lists failed deliveries.