# Artefaktum docs

> Core concepts behind Artefaktum, from artifacts and versions to search, lineage, and how bytes move

Artefaktum is a multi-tenant artifact store for AI agents and automated workflows that share no filesystem. An agent pushes a file with a descriptor; a different agent, on a different host, hours or days later, finds it by what it is rather than by an ID, and checks whether it is still current before it relies on it.

## Artifact

An artifact is the stable identity for a file. Your code sets its title, description, tags, and custom metadata when it pushes; the server fills in content type, size in bytes, and sha256 once the bytes land. Status moves through `pending_upload`, `processing`, `ready`, `failed`, `deleting`, `deleted`. `ready` means the object is verified in storage, not that it is searchable by meaning yet: semantic readiness is tracked separately as `semantic_ready`, so an embedding-provider outage never hides a new artifact from exact or text search, only from semantic.

## Versions

An artifact can have more than one version, and bytes are immutable: new content never overwrites a version, it opens one with `artifact_create_version` (`create_version` in the SDKs), and the server records a `supersedes` edge from the new version to the one before it. Search results and `artifact_get` return the latest version's metadata, content type, size, and sha256, by default. Older versions stay addressable by ID.

## external_key

`external_key` is a stable name your own code chooses, not one the server hands back, so re-running the same workflow, or a different workflow entirely, lands on the same artifact instead of creating a duplicate. `resolve` is built around it: pass an `external_key` and a `max_age_seconds`, and it returns `hit` when a fresh-enough artifact already exists, `create` with a signed upload URL when you are the caller that should produce it, or `pending` when another caller is already producing it. That is what lets several agents racing for the same expensive upstream response make it exactly once.

## Search modes

`artifact_search` supports four modes: `exact` (structured filters only, no query text needed), `text` (full-text over title, description, and tags), `semantic` (over the artifact descriptor), and `hybrid`, which fuses the text and semantic rank lists with Reciprocal Rank Fusion so no score calibration is needed. Scores are not comparable across modes. Any mode can be narrowed with filters on tags, content type, and dates.

## Relations and lineage

Artifacts link to each other with five relation types: `derived_from`, `supersedes`, `attachment_of`, `generated_by`, and `related_to`. Tag an upload or download with a `run_id` and the server infers `derived_from` edges automatically, pinned to the exact version that was read; an explicit relation always replaces an inferred one. Two trust signals ride along with search results and `artifact_get`: `superseded`, meaning another artifact has a `supersedes` edge pointing here, or a newer version of this same artifact exists; and `stale_upstream`, meaning something this artifact was derived from has since moved on: a new version, superseded, expired, or deleted. Superseded artifacts leave default search results; pass `exclude_superseded: false` to see the history.

## Projects and tenants

Every account or organisation is one tenant. Projects live inside a tenant, and every operation is scoped to a project. API keys carry scopes and can be limited to a single project or left tenant-wide, plus an optional expiry. Organisations share one plan and mint their own keys from the console.

## How bytes move

Uploading is two calls, never one: reserve an upload to get a signed PUT URL and headers, send the bytes straight to object storage, then call complete. Downloading mirrors that: ask for a download and get back a short-lived signed URL, then fetch it yourself. Neither the REST API nor MCP responses ever carry file bytes, only metadata and URLs. The SDKs hash the file locally on push and verify the sha256 digest on pull, raising an integrity error on a mismatch.

## Choose an integration

| Integration | Pick it when | Docs |
| --- | --- | --- |
| MCP | Your agent runs inside a host that speaks MCP, such as Claude Code or Cursor, and you want push, search, and pull as tool calls with nothing to install. | [/docs/mcp/](/docs/mcp/) |
| Python SDK | You are writing Python and want typed methods with retries and sha256 verification built in. | [/docs/python/](/docs/python/) |
| TypeScript SDK | You are writing Node, or a script for Bun, Deno, or Cloudflare Workers, and want a zero-dependency typed client. | [/docs/typescript/](/docs/typescript/) |
| CLI | You are scripting, or baking Artefaktum into a sandbox image or a CI step, and want a plain command. | [/docs/cli/](/docs/cli/) |
| n8n | You are building an n8n workflow and want a node with a credential, not a raw HTTP request. | [/docs/n8n/](/docs/n8n/) |
| REST | You are on Make, Zapier, anything with an HTTP step, or writing your own client. | [/docs/rest/](/docs/rest/) |

## For agents

The whole set is also available in one fetch: [/llms.txt](/llms.txt) is an index of every page, and [/llms-full.txt](/llms-full.txt) concatenates all of them. Every page on this site also exists as plain Markdown at `/docs/<slug>.md`.
