Artifacts
One place for what your assistants make, a page or a small package, versioned, opened in an isolated viewer and handed to your agents
An artifact is something an assistant made for you to keep: a report, a dashboard, a prototype, a diagram. It is one HTML page, or a small package of HTML, CSS, JavaScript, images, fonts and data. n8v keeps every version, opens it safely, and hands it to your agents when their work needs it.
Artifacts are in early access and stay off until n8v switches them on for an
account. While they are off there is no Artifacts page, the endpoints answer
403 artifacts_off and the tools are not listed.
Why it lives in n8v
A page an assistant makes in its own app stays in that app. Your agents cannot read it, the next assistant cannot change it, and nobody can say which version is the current one. In n8v an artifact:
- has one address that never expires, such as
https://n8v.online/artifacts/5f0c…; - keeps every version, with who published it, from where and what changed;
- is private until you share it;
- can be read, mounted and updated by your chats and your organizations' agents;
- records who read it and who changed it.
Your assistant
Over MCP, with
artifact_publishA script or a CI job
Over the API, with
POST /api/v1/artifactsA chat's agent
A directory or a file from its agent environment
An organization's agent
For its organization, never shared further by it
n8v checks
- The cap: 100 files, 2 MB a file, 3 MB a version
- File types, by extension
- Every text file, whole, for secrets
Private storage, versioned
Every publish is a new version. Nothing of it runs on n8v's servers.
The Artifacts page
In n8v: versions, files, compare, share, activity
The viewer
An isolated frame on
usercontent.n8v.nl, a site of its own
Used by chats and organization agents
A chat is started with up to 5 artifacts, or its agent opens one itself.
1. Mount
A version is unpacked read-only at
/tmp/artifacts/<id>/v<n>/2. Work
The agent reads it, and builds on a copy of its own
3. Publish back
A new version, through the same checks. The chat is linked on the artifact
Publish from an assistant
Ask an assistant that is connected to n8v to publish what it made. Try: "Publish this report to n8v as an artifact." It calls artifact_publish with a title and the files:
{
"title": "Q3 churn report",
"note": "First version, from the October export.",
"files": [
{ "path": "index.html", "text": "<!doctype html>…" },
{ "path": "assets/chart.js", "text": "…" },
{ "path": "assets/logo.png", "base64": "iVBORw0KGgo…" }
]
}A text file goes in text. A binary file, such as an image or a font, goes in base64. The assistant answers with the artifact's address:
Published "Q3 churn report" version 1 (3 files, 41.2 KB). Open it in n8v: https://n8v.online/artifacts/5f0c…A script or a CI job does the same with an API key that has artifacts:write:
curl -sS -X POST "https://n8v.online/api/v1/artifacts" \
-H "Authorization: Bearer $N8V_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: churn-report-1" \
-d '{"title":"Q3 churn report","files":[{"path":"index.html","text":"<!doctype html><title>Churn</title><h1>Churn, Q3</h1>"}]}'To change an artifact, publish again with its id (over the API, POST /api/v1/artifacts/{id}/versions). Send the whole package each time. See Artifacts in the API for every call and its answer.
A page can only load its own files and a few script, style and font hosts, so an assistant should put the data a page needs into the package. See What a page can and cannot do.
What a version may hold
| Rule | Value |
|---|---|
| Files | 1 to 100 |
| One file | 10 MB at most |
| A version | 25 MB at most, all files together. Files sent inline (text, base64) hold 3 MB together; put larger ones into an organization with upload_file first and pass each as file |
| Entry page | index.html at the top of the package, or the only HTML file. With several HTML files and no index.html, name one with entry |
| Paths | Relative, up to 200 characters, such as assets/app.js. No leading slash, no .., no backslash, no file or folder whose name starts with a dot. The same path twice is refused, whatever its case |
| Pages | html, htm |
| Styles, code | css, js, mjs, wasm, map |
| Data, text | json, csv, xml, txt, md, pdf |
| Images | svg, png, jpg, jpeg, gif, webp, avif, ico |
| Fonts | woff, woff2, ttf, otf |
| Sound, video | mp3, wav, ogg, mp4, webm |
| Title, note | A title of up to 120 characters, required for a new artifact. A note of up to 500 characters says what a version changed |
The file type comes from the extension, never from what the file claims to be. A file with any other extension is refused, and so is a version over the cap. Nothing is stored from a refused publish, and the answer names the file and the rule.
View it
Open an artifact on the Artifacts page of n8v, at /artifacts. The list filters by organization, repository and where the latest version came from (an assistant, the API, a chat or an organization agent). It searches titles and shows the archived ones on request.
An artifact's page shows the version you picked, live, with:
- a version picker, and the files of that version;
- compare, between any two versions;
- a zip download of the version;
- full screen, and a phone width to check a narrow layout;
- share, archive and the artifact's activity.
The address /artifacts/<id>?v=<n> opens one version directly. An assistant should give you this address: it never expires.
The isolated viewer
A page an assistant wrote is code from outside. n8v never serves it from its own site. It is served by a separate viewer on usercontent.n8v.nl, a different site from n8v.online, inside an isolated frame.
The app
n8v.online
- Your sign-in and its cookie
- Your chats, repositories and settings
- The Artifacts page: who sees what, every version
- Decides who may open a version, and signs the link
A signed view link
The only thing that crosses. One version, good for six hours.
The viewer
usercontent.n8v.nl
- No cookie: it is another site, and it sets none
- An opaque origin: no storage, no way to the app
- A content security policy on every answer
- The files of the one version a link names, nothing else
The app decides who may open a version and signs a view link for it. A view link names one version and is good for six hours. The viewer checks the signature and serves that version's files, and nothing else. A forged, changed or expired link gets one answer: it has expired.
What a page can and cannot do
A page can:
- run its own scripts and styles, inline or from its files;
- load its own files by relative path, and fetch them from script;
- load scripts, styles and fonts from
cdn.jsdelivr.net,cdnjs.cloudflare.com,unpkg.com,esm.shandcdn.tailwindcss.com; - show images, sound and video from its own files or from data it builds itself;
- open dialogs, open a link in a new tab and offer a download.
A page cannot:
- read any cookie or stored data: the frame has no origin of its own, so the browser gives it none;
- reach n8v: no session, no API, no page of the app;
- fetch from or post to any other address in the background, or load an image from another site;
- embed another site in a frame, or submit a form to a server;
- take its frame in n8v to another site: on the Artifacts page the frame shows the viewer and nothing else;
- use the camera, microphone, location or other device features;
- be framed by any site other than n8v.
These rules are sent with every answer of the viewer, so they hold when a page is opened directly too. A link in a page can still open another site in a new tab, as a link on any page can. The page holds nothing of your account to take along.
Versions and comparing
Every publish is a new version. A published version never changes, and nothing is deleted.
- Publishing with an
idadds a version. The assistant sends the whole package again, and a file that did not change is stored once. - Publishing exactly what the latest version holds publishes nothing. The answer says
unchanged. - A
titlesent with anidrenames the artifact. - Each version records who published it, from where (an assistant, an API key, a chat or an organization agent), when, and its note.
Compare shows what changed between two versions: each file added, removed or changed, with the changed lines for text files. A binary file is listed without lines, and so is a text file of more than 4,000 lines. An assistant reads the same with artifact_diff, which compares the latest version with the one before unless it names two.
Share it
An artifact is private until you say otherwise. Only its person changes who sees it.
| Who sees it | Meaning |
|---|---|
| Private | You, and assistants and keys you gave the artifact permissions |
| Organization | Also the members and the agents of its organization. If it is in none, name the organization when you share. It stays with the organization: if you leave it, you no longer see it |
| Link | You, plus anyone who opens the share link and passes its sign-in. Optionally only the email addresses you name, until a date, or fixed to one version |
A share link opens on the viewer, behind a Cloudflare Access sign-in that proves the reader's email address (a one-time code, GitHub or Google):
- It names up to 20 email addresses. With none, anyone who passes the sign-in opens it.
- It follows the latest version, unless you fix it to one.
- It can have an end date. Without one it works until you revoke it.
- Sharing by link again keeps the same link, so a link you sent stays good.
After the sign-in the reader is sent to a view that lasts 30 minutes. The viewer checks it against the share on every request. A reader who stays longer signs in again.
Revoke by setting the artifact to private or to its organization. The link stops at the reader's next request, also for files their browser already holds. Archiving ends the link too.
Archive takes an artifact out of the list. It takes no new versions while archived, and its share link stops. Nothing is deleted: restore it at any time. A share link has to be made again after a restore.
Use it in chats and organizations
An artifact is not only for reading. Your chats and your organizations' agents can work from one and publish the next version.
Start a chat with artifacts. Pass up to 5 artifacts when a chat starts, over the API (POST /api/v1/chats) or with the MCP tool start_chat:
{
"repo": "fieldnote/app",
"message": "Build the churn dashboard from this prototype.",
"artifacts": [{ "id": "5f0c…" }, { "id": "a91e…", "version": 2 }]
}Without a version the chat gets the latest. n8v unpacks each one, read-only, in the agent environment at /tmp/artifacts/<id>/v<n>/, and the agent's first message says where they are.
Tools in the agent environment. The agent of a chat, and every organization agent, has four tools:
| Tool | What it does |
|---|---|
artifact_list | Lists the artifacts it can see |
artifact_read | One artifact: its versions and the files of one |
artifact_open | Downloads a version into /tmp/artifacts/<id>/v<n>/, read-only |
artifact_publish | Publishes a directory or a file from the agent environment as a new artifact or a new version. Same cap, same scan for secrets |
Links. A chat that used an artifact or changed one is linked on the artifact's page, with the version and whether it used or changed it. You see the names of your own chats only.
Organization agents read and update the artifacts of their organization. A new artifact an organization agent publishes belongs to its organization and is visible to it. An organization agent never shares an artifact and never archives one: who sees an artifact stays a person's decision. For the same reason it cannot publish to an artifact shared by a link that follows the latest version; fix the link to a version, or publish that version yourself.
Security at a glance
- A site of its own. Pages are served from
usercontent.n8v.nl, never fromn8v.online. No cookie of the app reaches a page, and the viewer sets none. - Isolation. Every page runs isolated, without an origin of its own, in the frame and when opened directly: no cookie, no stored data, no way to the app.
- A content security policy on every answer. Nothing loads by default. A page gets its own files and the script, style and font hosts listed above. No other network, no frames, no form posts.
- Nothing runs on n8v's servers. n8v stores files and serves them. It never executes or renders a page. Thumbnails are rendered by Cloudflare Browser Rendering, from the same viewer under the same rules.
- Signed links. A view link opens one version for six hours. A share link sits behind a sign-in, and its 30 minute view is checked against the share on every request.
- A stated cap. 100 files, 10 MB a file, 25 MB a version (3 MB of it sent inline), file types by extension. Checked before anything is stored.
- Rate limits. A key's 120 calls a minute, and 30 published versions an hour per account.
- A scan for secrets. Every text file is scanned whole before it is stored: private keys, and keys and tokens of AWS, GitHub, Slack, Stripe, Google, Anthropic, OpenAI and n8v. A file named like a credentials file is refused by its name. A hit refuses the publish and names the file and the kind, never the value.
- An audit trail. Every API and MCP call is in your activity log as
artifact.*, by its shape and never with a file's content. Each artifact keeps its own trail: every publish, share, archive and restore, and every read or mount by an assistant or an agent. - Two permissions of their own.
artifacts:readandartifacts:write. An app or a key that reads your repository files does not read your artifacts, and the other way round.
Limits
| Limit | Value |
|---|---|
| Files in a version | 100 |
| One file | 10 MB |
| A version, all files | 25 MB |
| A publish request, whole | 4.4 MB |
| Files sent inline in one publish | 3 MB; larger files by reference (file, from upload_file) |
| Published versions per account | 30 an hour, across every key, app and agent |
| Calls per key | 120 a minute, as for the rest of the API |
| Title | 120 characters |
| Note | 500 characters |
| Path of a file | 200 characters |
| Email addresses on a share link | 20 |
| Artifacts a chat is started with | 5 |
| A view link | 6 hours |
| A share link's view, before signing in again | 30 minutes |
| Text of one file returned to an assistant | 200 KB. Longer is cut, and the answer says so |
| A binary file returned to an assistant | Up to 256 KB. Larger is described by type and size, not sent |
| Lines of a text file compared | 4,000. Longer is reported as changed, without the lines |
Over the hourly limit a publish answers 429 rate_limited with Retry-After.
Turn it on
Artifacts are behind the flag artifacts, which is off by default.
- The account. An admin switches the flag on for an account, or for everyone, under
/internal/admin/feature-flags. The Artifacts page appears, and chats can be started with artifacts. - Connected assistants. The two permissions, Read your artifacts and Publish artifacts, are switches of their own on the consent screen. An assistant that was connected before reconnects once: connect n8v again in Claude or ChatGPT and switch them on. Every connection of that app then has them, on every device.
- API keys. Give a key
artifacts:read(Read artifacts),artifacts:write(Publish artifacts) or both in Settings, API.
To check a connection, the assistant calls whoami, or a key GET /api/v1/me: each artifact tool is listed with whether it may be used and, if not, why. See What an assistant can read.
For assistants and scripts
| Tool | What it does | Needs |
|---|---|---|
artifact_publish | Publishes a new artifact, or a new version of one | artifacts:write |
artifact_list | Lists artifacts, by organization, repository, source or words of the title | artifacts:read |
artifact_read | One artifact: its versions, the files of one, its chats and its share link | artifacts:read |
artifact_file | The content of one file | artifacts:read |
artifact_diff | What changed between two versions | artifacts:read |
artifact_share | Sets who sees it: private, organization or link | artifacts:write |
artifact_archive | Archives or restores it | artifacts:write |
An assistant shares or archives only when you ask it to.
# List what the key can see
curl -sS "https://n8v.online/api/v1/artifacts?q=churn" \
-H "Authorization: Bearer $N8V_API_KEY"
# One artifact, with its versions and files
curl -sS "https://n8v.online/api/v1/artifacts/$ARTIFACT_ID" \
-H "Authorization: Bearer $N8V_API_KEY"
# What the latest version changed
curl -sS "https://n8v.online/api/v1/artifacts/$ARTIFACT_ID/diff" \
-H "Authorization: Bearer $N8V_API_KEY"See Artifacts in the API for every call, field and error.