Memory API
How requests behave
Acceptance, completion, replacement, recall and deletion, as your application observes them.
Copy page
Completion status
A send moves through processing, completed, or failed on GET /v1/memory/ingest/{ingestionId}. The status field reports processing while any item waits in the retry queue, failed if any item is set aside after repeated failures, and completed otherwise.
The response also carries settled and blocked:
settledistruewhen theraw,comprehension, andconsolidationcounters are 0 andfailedis 0.blockedistruewhen those three counters are 0 andfailedis above 0.
The readiness object reports four counters for the user's whole space:
raw: queued, no attempt yet.comprehension: queued with an attempt.consolidation: always 0.failed: set aside after repeated failures.
The failure field is null, or an object {code, message} with one of these codes: content-rejected (too large or permanent), model-unavailable (extraction exhausted), index-unavailable (transient exhausted), or internal.
Read failure.code to choose the next step. model-unavailable and index-unavailable are temporary: call POST /v1/memory/ingest/{ingestionId}/retry. content-rejected needs a change to the data point. internal goes to support with the X-Request-Id.
Source replacement
Send the same id again to replace a data point:
- An identical body returns
200withunchanged: true. - Any change creates a new revision. Harny deletes the memories built on the old revision, then ingests the new text. Fields you leave out of the resend keep their stored values.
- If the new text is refused, the data point has no memories until you send it again. That resend counts as a change.
- Sending an
idthat was deleted returns409withdata-point-deleted.
Idempotency keys
An idempotency key is a label you choose for one send. If the same send arrives twice, Harny stores it once, so it is safe to retry after a timeout.
Send idempotencyKey (at most 200 characters) with POST /v1/memory/ingest or POST /v1/memory/ingest/batch. A key is scoped to the app and user, and keys never expire.
- The same key with the same body returns the original receipt and original status code. Nothing new starts, including while the first request is still running. A claim still
processingafter 5 minutes is resumed. - The same key with a different body returns
409withidempotency-conflict.
An omitted timestamp is not included in the hash, so a retry hashes the same.
Retries
A batch that is refused partway keeps the items accepted before the refusal. The error includes data: {ingestionId, accepted: k}. Retry with the same idempotencyKey and body to resume at item k.
To re-run a send that stopped, call POST /v1/memory/ingest/{ingestionId}/retry. A retry is free.
Point in time
Recall accepts three parameters:
queryTimestampdrops results whoseoccurredAtis later. Results with unknown time are kept.asOfechoesqueryTimestamp, or the current time if it is omitted.occurredFromandoccurredTo(inclusive) keep only results inside the window. Results with unknown time are dropped.
These are filters over the assembled result, not retrieval restrictions. occurredFrom later than occurredTo returns 400 with recall-range-invalid.
User and audience
Name the person with the X-Harny-User: <user> header on app-key calls (fsa_). A user key (fsk_) names its own user and needs no X-Harny-User header.
A body identity never selects the user. If you send one, it must match the acting user, or the call returns 403 with identity-mismatch.
audience accepts only the omitted value or project. Any other value returns 400 with audience-unknown.
Request ids
Every response carries an X-Request-Id header. Error bodies have the shape {code, status, debugMessage, data}, with data null unless given.
Health
GET https://api.harny.ai/health returns {"status": "ok"} with no key. Use it for a liveness check.
Limits and the meter
Harny meters monthly-active end users. The first 500 in your active app are free for good. A user counts in a month when they used the app that month. Pricing lists the plans.
Batch ingestion accepts up to 1,000 items and 16 MiB of UTF-8 in total. Each item in a batch counts against your quotas on its own. GET /v1/memory/usage reports the current month's count.
A call over the per-minute limit returns 429 with an empty body and a Retry-After header.