On this page

Protocole de téléchargement

Résoudre un artifact, lire le plan hébergé, télécharger avec reprise par plages, vérifier SHA-256 et attester la fin.

Télécharger un fichier de modèle hébergé en toute sécurité : trouver l’artifact, lire le plan de téléchargement, suivre la redirection, vérifier le hash et attester la fin.

En bref

  1. Rechercher ou résoudre un dépôt vers un id d’artifact.
  2. Lire GET /api/v1/artifacts/{id}/download-plan. Se fier à serve.downloadReady et serveExplanation.serveVerdict — pas au status stockage obsolète.
  3. Choisir une ligne files[] avec downloadUrl. Open the file's downloadUrl (/api/downloads): it re-checks and redirects to a signed link that lasts at most 300s (default 300, configurable shorter). Reopen for a fresh link. A URL is not permission.
  4. Télécharger les octets (Range pour reprendre), vérifier sha256 en local, puis POST sur /api/download-completions/{id}/{path} avec X-Hugging-Bay-Completion-Token du redirect.

Sous-ensemble OpenAPI public : /openapi-public.json. Contrat complet : /openapi.json.

Endpoint changes in this source candidate

Protocol revision 2026-10-20-candidate-1. Package publication and product releases are recorded separately in the changelog.

  • /api/v1/search: Optional snapshot query pins complete public search metadata; unpinned behavior is unchanged.
  • /api/v1/resolve: Optional snapshot query pins resolved public identity; missing/unsupported references retain 404/400.
  • /api/v1/artifacts/{id}/files: Optional snapshot query pins bounded public file inventory; partial/degraded reads are never frozen.
  • /api/v1/artifacts/{id}/download-plan: Existing snapshot pins remain; clients carry the same pin across discovery and plan selection.
  • /openapi-public.json: Public read profile projects canonical schemas and their referenced components from the full contract.
  • /api/downloads/{id}/{path}: No authority change: every redirect is fresh and the final bytes must match the selected plan hash/size.

Pin the whole metadata path with snapshot: search, resolve, files, finder and plan. Pins retain per-instance answers for about one hour. Check X-Hugging-Bay-Snapshot-State; an unfrozen answer, restart or different instance does not guarantee identical metadata. Byte authorization is checked again when obtaining a fresh redirect. Keep the selected hash and size when renewing a URL.

En cas d’échec

  • HTTP 429 or 503 on plan/search/resolve Wait Retry-After (or retry_after_s in JSON), add jitter, then retry the same read.
  • HTTP 302 Location expires or returns 403 GET the same /api/downloads/{id}/{path} again without following redirects to mint a fresh signed URL (≤300s).
  • Partial download interrupted Resume with Range: bytes=<received>- on the signed URL until sizeBytes match the plan row.
  • serve.downloadReady is false or downloadUrl is missing Stop. Read serveExplanation.reason and reasonCodes; do not guess another path.
  • Local SHA-256 ≠ files[].sha256 Discard the file. Do not attest. Fetch a fresh copy from a new redirect.
  • POST /api/download-completions returns 200 Token already consumed; do not retry the POST.
Plus : champs du schéma, erreurs et spec lisible par les agents

Champs du plan (générés du schéma)

  • schemaVersion (required): object = "hugging-bay.artifact-download-plan.v1"
  • generatedAt (optional): string
  • artifactId (required): The one id key every surface uses (same as artifact.id).
  • artifact (required): object
  • status (optional deprecated): DEPRECATED for availability: the canonical STORAGE state (e.g. complete-bytes = bytes are stored) — NOT an obtainability, runnability or verification claim. It stays complete-bytes on a withheld artifact. Read `serve.downloadReady` / `serveExplanation.serveVerdict` instead.
  • serve (required): The single non-contradictory obtain contract (hugging-bay.serve-contract.nv5). Agrees with every per-file affordance below.
  • serveVerdict (optional): Top-level obtain verdict, same evaluation as serveExplanation.serveVerdict.
  • serveExplanation (required): The plain-words twin of `serve`, from the same evaluation (same serveEvaluationId).
  • serveEvaluatedAt (optional): string
  • serveEvaluationId (optional): string
  • files (required): Hosted file rows. A row is LISTED for inventory even when withheld; only a row with a non-false `url`/`downloadUrl` is downloadable now.
  • stats (optional): Counts over `files`: `files` = rows downloadable now, `listedFiles` = rows listed (including withheld), `withheldFiles` = listed minus downloadable.
  • manifest (optional): object
  • canonicalState (optional): object
  • completionAttestation (optional): object
  • fileIntegrity (optional): object
  • verify (optional): object
  • commands (optional): array
  • runCommands (optional): Recorded shell invocations for the selected exact file when run-command evidence is available. Each command names the tool (llama.cpp, Ollama, LM Studio), exact path, SHA-256, shell command and provenance (testedOn host, testedAt, runnerVersion). status is not-tested-yet when no sealed run kit matches.

Chaque ligne files[] (générée du schéma)

  • path (required): string
  • sizeBytes (required): integer
  • sha256 (required): The full published SHA-256 of the exact bytes; verify locally with `sha256sum <file>` (older Mac: `shasum -a 256 <file>`).
  • url (optional deprecated): Legacy alias of downloadUrl; false/null when withheld.
  • downloadUrl (optional): Canonical byte-download URL. Responds HTTP 302 to signed storage; follow redirects.
  • canonicalUrlField (optional): One canonical byte URL per row. = "downloadUrl"
  • downloadUrlResponse (optional): object
  • verifiedDownloadUrl (optional): Server-stream-verified lane, when available.
  • completionAttestationUrl (optional): POST here after a full download + local SHA-256 match, with the X-Hugging-Bay-Completion-Token from the redirect.
  • contentType (optional): string
  • role (optional): string

Codes d’erreur

codeHTTPmeaning / retry
invalid_query400A query parameter is missing, malformed, or outside its documented enum or numeric range. Carries field and (for enums) allowed. Rejected at the edge before the database.
artifact_not_found404No public artifact has that id (anonymous caller). next.command searches the catalog for it.
file_withheld404The file lane refused bytes because the live file admission or artifact obtain verdict withheld them (410 for withdrawn bytes or reason_code artifact_obtain_not_ready). Files withheld — not faked; next.command reads the download-plan, whose serveExplanation says why. Artifact-verdict denials include obtainReady, serveVerdict, reasonCodes, reason, serveEvaluatedAt and serveEvaluationId. reason_code carries the lane code.
rate_limited429Too many requests in the current window. Wait retry_after_s seconds (also in Retry-After), then retry. See x-rate-limit.
service_unavailable503A bounded authority read failed closed or capacity was saturated. The document is never fabricated; wait retry_after_s seconds (always in the body), then retry.
completion_token_invalid403Re-open the download URL (do not follow the 302) for a fresh X-Hugging-Bay-Completion-Token, then POST again.
digest_mismatch409Do not retry the POST with the same bytes; re-download and re-hash locally.
signed_url_expired403GET the plan downloadUrl again; signed storage links last at most 300s.
range_not_satisfiable416Fix the Range header against sizeBytes from the plan row.

Spécification lisible par agent (texte brut)

Hugging Bay download protocol
schemaVersion: hugging-bay.artifact-download-plan.v1
generatedFrom: openapi-developer-contract DOWNLOAD_PLAN_SCHEMA
digest: sha256:3876839c070233c434ee8ac37b3f604b12647c5ea5dae4cf51f4b82eac618a14

Summary
- Find an artifact (search or resolve), read its download-plan, download only rows with downloadUrl when serve says READY.
- Open the file's downloadUrl (/api/downloads): it re-checks and redirects to a signed link that lasts at most 300s (default 300, configurable shorter). Reopen for a fresh link. A URL is not permission.
- Verify SHA-256 locally, then POST completion with the redirect token.

Obtain authority
- serve.downloadReady and serveExplanation.serveVerdict (READY / BLOCKED / PENDING / UNKNOWN)
- Legacy top-level status is storage-only: DEPRECATED for availability: the canonical STORAGE state (e.

Plan fields (from schema)
schemaVersion (required): object = "hugging-bay.artifact-download-plan.v1"
generatedAt (optional): string
artifactId (required): The one id key every surface uses (same as artifact.id).
artifact (required): object
status (optional deprecated): DEPRECATED for availability: the canonical STORAGE state (e.g. complete-bytes = bytes are stored) — NOT an obtainability, runnability or verification claim. It stays complete-bytes on a withheld artifact. Read `serve.downloadReady` / `serveExplanation.serveVerdict` instead.
serve (required): The single non-contradictory obtain contract (hugging-bay.serve-contract.nv5). Agrees with every per-file affordance below.
serveVerdict (optional): Top-level obtain verdict, same evaluation as serveExplanation.serveVerdict.
serveExplanation (required): The plain-words twin of `serve`, from the same evaluation (same serveEvaluationId).
serveEvaluatedAt (optional): string
serveEvaluationId (optional): string
files (required): Hosted file rows. A row is LISTED for inventory even when withheld; only a row with a non-false `url`/`downloadUrl` is downloadable now.
stats (optional): Counts over `files`: `files` = rows downloadable now, `listedFiles` = rows listed (including withheld), `withheldFiles` = listed minus downloadable.
manifest (optional): object
canonicalState (optional): object
completionAttestation (optional): object
fileIntegrity (optional): object
verify (optional): object
commands (optional): array
runCommands (optional): Recorded shell invocations for the selected exact file when run-command evidence is available. Each command names the tool (llama.cpp, Ollama, LM Studio), exact path, SHA-256, shell command and provenance (testedOn host, testedAt, runnerVersion). status is not-tested-yet when no sealed run kit matches.

Per-file row (from schema)
  path (required): string
  sizeBytes (required): integer
  sha256 (required): The full published SHA-256 of the exact bytes; verify locally with `sha256sum <file>` (older Mac: `shasum -a 256 <file>`).
  url (optional deprecated): Legacy alias of downloadUrl; false/null when withheld.
  downloadUrl (optional): Canonical byte-download URL. Responds HTTP 302 to signed storage; follow redirects.
  canonicalUrlField (optional): One canonical byte URL per row. = "downloadUrl"
  downloadUrlResponse (optional): object
  verifiedDownloadUrl (optional): Server-stream-verified lane, when available.
  completionAttestationUrl (optional): POST here after a full download + local SHA-256 match, with the X-Hugging-Bay-Completion-Token from the redirect.
  contentType (optional): string
  role (optional): string

Serve verdicts
READY, BLOCKED, PENDING, UNKNOWN

Snapshot scope: search, resolve, file inventory, finder and plan accept snapshot. Pins freeze metadata per instance, not signed URLs or byte authority. Check X-Hugging-Bay-Snapshot-State; unfrozen is not an immutable answer. Restart or another instance can miss a prior answer. A 410 requires restarting the metadata chain with a fresh pin. Download bytes must still match the selected plan hash and size.

Endpoint changes in this source candidate (publication is separate)
- /api/v1/search: Optional snapshot query pins complete public search metadata; unpinned behavior is unchanged.
- /api/v1/resolve: Optional snapshot query pins resolved public identity; missing/unsupported references retain 404/400.
- /api/v1/artifacts/{id}/files: Optional snapshot query pins bounded public file inventory; partial/degraded reads are never frozen.
- /api/v1/artifacts/{id}/download-plan: Existing snapshot pins remain; clients carry the same pin across discovery and plan selection.
- /openapi-public.json: Public read profile projects canonical schemas and their referenced components from the full contract.
- /api/downloads/{id}/{path}: No authority change: every redirect is fresh and the final bytes must match the selected plan hash/size.

Retry rules
- HTTP 429 or 503 on plan/search/resolve: Wait Retry-After (or retry_after_s in JSON), add jitter, then retry the same read.
- HTTP 302 Location expires or returns 403: GET the same /api/downloads/{id}/{path} again without following redirects to mint a fresh signed URL (≤300s).
- Partial download interrupted: Resume with Range: bytes=<received>- on the signed URL until sizeBytes match the plan row.
- serve.downloadReady is false or downloadUrl is missing: Stop. Read serveExplanation.reason and reasonCodes; do not guess another path.
- Local SHA-256 ≠ files[].sha256: Discard the file. Do not attest. Fetch a fresh copy from a new redirect.
- POST /api/download-completions returns 200: Token already consumed; do not retry the POST.

Error codes (download path)
- invalid_query (400): A query parameter is missing, malformed, or outside its documented enum or numeric range. Carries field and (for enums) allowed. Rejected at the edge before the database.
- artifact_not_found (404): No public artifact has that id (anonymous caller). next.command searches the catalog for it.
- file_withheld (404): The file lane refused bytes because the live file admission or artifact obtain verdict withheld them (410 for withdrawn bytes or reason_code artifact_obtain_not_ready). Files withheld — not faked; next.command reads the download-plan, whose serveExplanation says why. Artifact-verdict denials include obtainReady, serveVerdict, reasonCodes, reason, serveEvaluatedAt and serveEvaluationId. reason_code carries the lane code.
- rate_limited (429): Too many requests in the current window. Wait retry_after_s seconds (also in Retry-After), then retry. See x-rate-limit.
- service_unavailable (503): A bounded authority read failed closed or capacity was saturated. The document is never fabricated; wait retry_after_s seconds (always in the body), then retry.
- completion_token_invalid (403): Re-open the download URL (do not follow the 302) for a fresh X-Hugging-Bay-Completion-Token, then POST again.
- digest_mismatch (409): Do not retry the POST with the same bytes; re-download and re-hash locally.
- signed_url_expired (403): GET the plan downloadUrl again; signed storage links last at most 300s.
- range_not_satisfiable (416): Fix the Range header against sizeBytes from the plan row.

# Worked example: resolve → plan → download (resume) → verify → attest
# Requires curl, jq and either sha256sum (Linux) or shasum (Mac). Choose a repo and an exact path from its plan.
set -eu
BASE='https://huggingbay.xyz'
REPO='Qwen/Qwen2.5-0.5B-Instruct-GGUF'
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT
PIN=$(curl -fsS "$BASE/api/v1/snapshot" | jq -er '.snapshotId')
curl -fsS --get --data-urlencode "repo=$REPO" --data-urlencode "snapshot=$PIN" "$BASE/api/v1/resolve" > "$WORK/resolve.json"
ARTIFACT=$(jq -er '.artifactId' "$WORK/resolve.json")
curl -fsS --get --data-urlencode "snapshot=$PIN" "$BASE/api/v1/artifacts/$ARTIFACT/download-plan" > "$WORK/plan.json"
jq -e '.serve.downloadReady == true' "$WORK/plan.json" > /dev/null
# Inspect files[] and choose FILE explicitly; this example chooses the first READY GGUF.
jq -e '[.files[] | select(.downloadUrl != null and (.path | endswith(".gguf")))][0] | select(. != null)' "$WORK/plan.json" > "$WORK/file.json"
HASH=$(jq -er '.sha256 | sub("^sha256:"; "") | ascii_downcase | select(test("^[0-9a-f]{64}$"))' "$WORK/file.json")
BYTES=$(jq -er '.sizeBytes | select(type == "number" and . >= 0 and floor == .)' "$WORK/file.json")
DOWNLOAD=$(jq -er '.downloadUrl' "$WORK/file.json")
case "$DOWNLOAD" in "$BASE/api/downloads/$ARTIFACT/"*) ;; *) exit 1 ;; esac
# The signed redirect and capability are fresh, never snapshot-cached. Do not log them.
curl -fsS -D "$WORK/headers" -o /dev/null "$DOWNLOAD"
TOKEN=$(awk 'tolower($1)=="x-hugging-bay-completion-token:" {gsub("\r", "", $2); print $2}' "$WORK/headers")
LOC=$(awk 'tolower($1)=="location:" {gsub("\r", "", $2); print $2}' "$WORK/headers")
test -n "$TOKEN" && test -n "$LOC"
# Re-run this transfer with a fresh redirect if its signed URL expires. Keep HASH and BYTES.
curl -fsSL -C - -o model.gguf.part "$LOC"
test "$(wc -c < model.gguf.part | tr -d ' ')" = "$BYTES"
if command -v sha256sum > /dev/null 2>&1; then
  printf '%s  model.gguf.part\n' "$HASH" | sha256sum -c -
else
  printf '%s  model.gguf.part\n' "$HASH" | shasum -a 256 -c -
fi
# Completion route follows the plan-selected file, not a guessed filename.
COMPLETION=$(printf '%s' "$DOWNLOAD" | sed 's#/api/downloads/#/api/download-completions/#')
jq -n --arg sha256 "$HASH" --argjson sizeBytes "$BYTES" --arg completionToken "$TOKEN" '{sha256:$sha256,sizeBytes:$sizeBytes,completionToken:$completionToken}' > "$WORK/completion.json"
curl -fsS -X POST -H 'content-type: application/json' --data-binary @"$WORK/completion.json" "$COMPLETION"
mv model.gguf.part model.gguf
Quick answer: compatibility and sources

How do I use Protocole de téléchargement?

It depends on your client and setup. Résoudre un artifact, lire le plan hébergé, télécharger avec reprise par plages, vérifier SHA-256 et attester la fin. Check the current file record before downloading. Metadata access, file hosting and a tested runtime are separate things.

Model weights are learned parameters; a runtime is the software that loads them. RAM is working memory, separate from disk space for downloaded files.

Page-copy provenance: the revision record names apps/web/server.mjs, apps/web/lib/aeo-page.mjs, apps/web/lib/api-status-contract.mjs, apps/web/lib/agent-readable.mjs, apps/web/lib/docs-hub-model.mjs, apps/web/lib/compare-pages.mjs and commit 8871bab84e1cf80aea1686a944ec335078a6c036. This identifies the text source; it is not a model test receipt. A SHA-256 checksum fingerprints file bytes, not safety or answer quality. See what file verification checks. Run receipts, when present, belong to a specific model file and setup; this page asserts no model test.

Page sources and update history

Updated · Page-copy source revision 8871bab84e1cf80aea1686a944ec335078a6c036 · Source files: apps/web/server.mjs, apps/web/lib/aeo-page.mjs, apps/web/lib/api-status-contract.mjs, apps/web/lib/agent-readable.mjs, apps/web/lib/docs-hub-model.mjs, apps/web/lib/compare-pages.mjs · Full revision record

Key facts

Catalog vs runtime
Metadata access, file hosting and a tested load are separate checks.
Checksum
SHA-256 confirms file identity, not license permission or answer quality.
Receipts
Run evidence is scoped to one file and setup; it does not transfer to other files.

Evidence you can inspect (plain text)

  • GET /openapi.json lists request and response shapes for public API reads.
  • GET /api/agent-discovery lists agent-facing interfaces when enabled.
  • Open /artifact/hf-model-qwen-qwen3-8b/files for model exact filenames, availability and any recorded SHA-256.
  • Open /evidence/artifacts/hf-model-qwen-qwen3-8b for run-readiness evidence tied to that record; absent receipts stay unmeasured.
  • Open /api/artifacts/hf-model-qwen-qwen3-8b/card.md for machine-readable source facts (not a runtime test).
  • These documents describe interfaces and catalog reads; they do not execute or score models.

Unmeasured states are stated explicitly; this page does not invent run scores or compatibility guarantees.

Which date applies to which fact

  • Committed page-copy sources:
  • Upstream model metadata: Dates on artifact records when shown; not implied by page-copy revision
  • Run receipts: Only on /evidence pages when recorded; otherwise unmeasured

Page-copy revision (Updated line above) identifies committed text sources, not upstream model edits or test outcomes.