Research
Package research is every experiment you have ever run, kept and comparable.
Package research is every experiment you have ever run, kept and comparable.
| Base URL | https://api.hanzo.ai |
| Operations | 8 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
research
GET /v1/research/artifacts/{sha256}
Fetch one recorded artifact's bytes by its content hash.
Streams the artifact's stored bytes — the retrieval half of hash-addressing, where the diary feed hands out hashes and this hands back what they name. The Content-Type is image/png when the artifact was recorded as a snapshot and application/octet-stream otherwise; it comes from the recorded KIND, not from sniffing the bytes, so an artifact filed as a report always arrives as opaque bytes.
The hash is an address, and the read is NOT global. The store file IS the org, so the same bytes recorded by two tenants are two artifacts, and a hash that exists but belongs to somebody else is a 404 exactly like one that was never recorded — knowing a content hash is never enough to read it. A caller with no validated org is refused 403 outright.
Project narrows further INSIDE that org: the artifact's project must equal the caller's, which is ?project= when given and otherwise the caller's own project scope, defaulting to the default project. So an artifact filed under a named project is not found until the caller names that project — a mismatch is the same 404 an unknown hash gets, never a distinguishable refusal.
The address can be trusted because the WRITE derived it: the server hashes the bytes it stores, inside the trust boundary, and refuses a client-supplied sha256 that disagrees with them, so poisoning a first write would take a preimage. This read does not re-hash — it looks the hash up as a key.
One shape to expect: this route writes its errors IN-BAND as {"error": …} at the real status code, not the {status, error} envelope the typed ops beside it return. It is mounted under an error-flattening filter that would otherwise rewrite its 4xx, so the body is written before that filter runs. A store that cannot be opened is a 500.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
sha256 | path | string | yes |
GET /v1/research/artifacts
Returns the caller org's research-diary feed newest-first — the snapshots and reports tied to its runs, as metadata and content addresses; the bytes themselves are fetched by hash. ?run= narrows to one run, ?project= to one project (default the caller's project scope), and ?since= to a unix second.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | — | Project narrows to one project. |
run | query | string | — | Run narrows to one run's artifacts by its stable id. |
since | query | integer | — | Since bounds the feed to artifacts recorded at or after this unix second. |
POST /v1/research/artifacts
Records one research-diary artifact — a board snapshot or a
generated report — CONTENT-ADDRESSED inside the trust boundary. The caller submits
the bytes as base64 content; the SERVER hashes them and THAT hash is the identity
and the ref, so the address can never be poisoned by a client-asserted one. A
client-supplied sha256, if present, must match the bytes. The project is the
SERVER's value and visibility is forced private. Re-posting the same bytes is a
no-op that reports created=false.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
content | string | — | base64 bytes on write; the server hashes + stores them (never returned) |
git_branch | string | — | |
git_dirty | boolean | — | |
git_sha | string | — | |
kind | string | — | |
lib_versions | — | ||
project | string | — | |
ref | string | — | server-derived content address (sha256:<hash>) |
retention_class | string | — | |
run_id | string | — | |
sha256 | string | — | SERVER-derived on write; the identity |
ts | integer | — | |
visibility | string | — |
GET /v1/research/experiments
Returns the caller org's CANONICAL experiments — the deterministic deduped view over the versioned history. With no ?project= it reads the org's whole set across projects (the ops board's cross-project view, since a project is a sub-scope of the one tenant); ?project= narrows to one and ?kind= to one discriminator.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | — | Project narrows to one project. |
kind | query | string | — | Kind narrows to one discriminator: benchmark, kernel-perf, training, ablation or policy-eval. |
POST /v1/research/experiments
Appends one batch of experiment and attempt versions to the caller org's evidence store, idempotently by content, then rolls it up to the analytics plane best-effort. The project is the SERVER's value and visibility is forced private — an upload grants no training or publication right, which is a separate call. A run carrying a BYO endpoint is SSRF-checked before the store is touched. The answer carries BOTH the canonical (deduped) and retained (full history) counts, so a caller sees the versioned truth rather than a dedup that reads as loss.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
attempts | Attempt[] | — | |
experiments | Experiment[] | — |
POST /v1/research/grants
Records the SEPARATE authorization an upload never
implies: a record's visibility (private, org or public) and, for a run, its
training and commons-publication consent. Address a run by its stable id or an
artifact by its sha256; an artifact grant sets visibility only. The ORG is the
tenant boundary and comes from the validated principal, so a caller can only ever
grant within its own org; project locates WHICH record inside it and defaults to
the caller's project scope.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
id | string | — | an experiment (run) stable id |
project | string | — | |
publishable | boolean | — | |
sha256 | string | — | OR an artifact content hash |
trainable | boolean | — | |
visibility | string | — |
GET /v1/research/projects
Returns every research project in the caller's org with its real totals — canonical and retained side by side — which is the ops board's "every project + real totals" view.
GET /v1/research/totals
Returns the caller org's headline aggregate plus a per-kind breakdown — the observatory's poll target. Canonical and retained counts travel together, so a deduped view never reads as loss. ?project= narrows to one project.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | — | Project narrows the aggregate to one project. |
How is this guide?
Rerank
Package ai is Hanzo AI — the model API on /v1 (/v1/chat/completions, /v1/messages, /v1/models and the rest of hanzoai/ai's surface) — mounted into a cloud binary with the money, ingest and telemetry…
Responses
Package ai is Hanzo AI — the model API on /v1 (/v1/chat/completions, /v1/messages, /v1/models and the rest of hanzoai/ai's surface) — mounted into a cloud binary with the money, ingest and telemetry…