37 tools, all scoped to the websites the token’s owner can reach.
Every one takes an optional tenant_id, the site’s friendly id as get_site returns
it, and works on the account’s original site when it is left out; it is not repeated
under each tool below. A token that may only read is offered the 19 that ask for
no more, and tools/list names exactly what a connection may call.
Reading
Section titled “Reading”get_site
Section titled “get_site”Get site overview. Scope site:read, read-only.
The selected website: its friendly id, name, public address, every
live page with its path and file, the branches ahead of main
(pending_branches; list_branches has their preview URLs), and a
preview URL for the live site. Also its languages, its tables (with
how many posts are published beside their records), its
JavaScript files, and its plan: limits, usage, and whether the site
is frozen.
Takes nothing beyond tenant_id.
Notifications
Section titled “Notifications”list_notifications
Section titled “list_notifications”Read what the owner has been told. Scope site:read, read-only.
What the owner has been told about this site, newest first: the alerts
on the Notifications screen of their dashboard. Each says what
happened, when (received_at), and whether it is still unread
(unread). Call it when the owner asks what is wrong with their
site or what has happened on it. get_site says how many are unread.
Arguments:
kind(string, one ofform_submission,page_degraded,plan,script_failed,site_transfer): Only the alerts of this kind. Leave it out for every kind.unread(boolean): true for only the alerts that are still unread.
Vocabulary
Section titled “Vocabulary”describe_vocabulary
Section titled “describe_vocabulary”Describe the site vocabulary. Scope site:read, read-only.
Everything a site’s files may say, generated from the running code rather than written down, so it is never out of date. Topic language is the whole of vzk on one card; the rest are the platform’s: looks, behaviors, javascript, fields, meta, layout, sites and guides.
Arguments:
topic(string, one oflooks,behaviors,javascript,fields,meta,layout,sites,guides,language): Which part of the vocabulary to describe. Defaults to language.name(string, one ofapps,building,claret,cobalt,copying,instructions,mineral,photographer,photographer/blog,photographer/blog/[slug],photographer/index,photographer/services,photographer/work,photographer/work/[slug],playbooks/photographer,playbooks/plumber,plumber,plumber/index,plumber/prices,press,publication,starter,starter/index,vizitka,vizitka/about,vizitka/acceptable-use,vizitka/cookies,vizitka/data-deletion,vizitka/dpa,vizitka/index,vizitka/legal,vizitka/legal-notice,vizitka/pricing,vizitka/privacy,vizitka/subprocessors,vizitka/terms,vzk/authoring,vzk/javascript,vzk/languages,vzk/pages,vzk/styling,vzk/tables,vzk/tests): With topic=looks, sites or guides, return only this one.
Check a change without writing it. Scope site:read, read-only.
Says what write_files would say of a change, without writing it: up to
50 files written, deleted or moved over a branch or
a commit (default main), checked as a commit is. Answers ok, each
refusal under problems with its file, the compiler’s warnings,
and what a write would fix and format in a .vzk file, under
would_apply and would_format.
Arguments:
ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.files(array of object, required): Each file with exactly one of content, delete or move_to.path(string, required): The file, such as pages/about.vzk.content(string): The whole new text of the file.delete(boolean): true to delete the file.move_to(string): A new path for the file, its text unchanged.
list_files
Section titled “list_files”List the site’s files. Scope site:read, read-only.
Every picture on this site’s disk, newest first: its name, what kind of
file it is, how big it is, the public URL it is served at, and a
reference ready to write in a page. The favicon (the icon browsers
show in a tab) is in the list, marked kind: "favicon"; an ordinary
image goes on a page as <img src={assets["<key>"]}>, or anywhere
else a path belongs (guide vzk/pages, Pictures).
Takes nothing beyond tenant_id.
get_disk_usage
Section titled “get_disk_usage”Check how much storage the site has left. Scope site:read, read-only.
How much of this site’s storage is used and how much is left, in bytes.
Ask before telling the owner to upload something, so “add three photos
to the gallery” does not end with them meeting a refusal you could have
seen coming. list_files is what is actually stored.
picture_metadata is what the site does with a camera’s notes on the
next upload: archive and discard serve visitors a copy with them
taken off, while publish serves the file as it arrived, so the
camera, the moment and, from a phone, the location go out with it. Say
which one is in effect when you upload a photograph for somebody. You
cannot change it; the owner does, on the Disk screen.
Takes nothing beyond tenant_id.
prepare_file_upload
Section titled “prepare_file_upload”Prepare a local file upload. Scope site:write, writes.
Prepares an ordinary HTTP upload for a picture that is available as a
local file but cannot be put into an MCP argument. Call this instead of
base64-encoding a local photo or icon. For a picture already at a
public https address, use upload_file directly instead.
Arguments:
kind(string, one ofimage,favicon,social_image, required): What the file is for: image (an ordinary picture, answered with the public URL it is served at); favicon (the site’s tab icon — replaces the current one, live at once); social_image (the picture a shared link to this site shows — replaces the current one, live at once, and cropped to 1200×630 from the middle).
upload_file
Section titled “upload_file”Put a file on the site’s disk. Scope site:write, writes.
Puts a file on this site’s disk, from exactly one source: a picture the
customer attached in this conversation (file), a public https address
(url), or base64 bytes (data). Only raster images are accepted (PNG,
JPEG, WebP), and the bytes are identified on arrival: a file that is not
really a picture is refused whatever it is named. When the customer has
attached the picture to this conversation, file is the source to use:
pass that attachment and the client supplies the address. For a local
file on a machine with a shell, do not base64 it either: call
prepare_file_upload and POST it as multipart form data instead.
Arguments:
kind(string, one ofimage,favicon,social_image, required): What the file is for: image (an ordinary picture, answered with the public URL it is served at); favicon (the site’s tab icon — replaces the current one, live at once); social_image (the picture a shared link to this site shows — replaces the current one, live at once, and cropped to 1200×630 from the middle).file(object): The picture the customer attached to this conversation. When there is an attachment and it is the thing to store, pass it here and the client fills in its address. Never write a download_url of your own — a link given to you as text goes inurlinstead.download_url(string, required): A public https address the file can be fetched from.file_id(string, required): The client’s own id for the file.mime_type(string): What the client believes the file is. Advisory only: the bytes are identified on arrival, and it is they that decide.file_name(string): What to call the file, when the client knows.
url(string): A public https address to fetch the file from.data(string): The file’s bytes, base64-encoded. A data: URL is fine too.filename(string): What to call the file. Required with data. With file the client’s own name is used when this is left out, and with url the address’s own last segment.
list_tree
Section titled “list_tree”List the site’s files. Scope site:read, read-only.
Every file of the site’s code (pages, layouts, components, locales, scripts, stylesheet, import map) at a branch or a commit, with its kind and size. Defaults to main. Read the text with read_files.
Arguments:
ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.
read_files
Section titled “read_files”Read some of the site’s files. Scope site:read, read-only.
The text of up to 20 files at a branch or a commit (default main), with the commit read, which write_files takes as base. list_tree names the files; describe_vocabulary topic layout explains them.
Arguments:
paths(array of string, required): File paths from list_tree, such as pages/index.vzk.ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.
outline
Section titled “outline”Outline the site or one file. Scope site:read, read-only.
The map of a site written in vzk at a branch or a commit (default main): its files, or with path one file’s blocks, each with its address, lines, size and note. Read one with read_block. describe_vocabulary topic language teaches vzk.
Arguments:
path(string): A .vzk file, such as pages/index.vzk, to list its blocks. Omit for the site’s files.ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.
describe
Section titled “describe”Describe what the blocks do. Scope site:read, read-only.
What the blocks of a site written in vzk do, in sentences made from their code alone, at a branch or a commit (default main): with path every block of one file, with address one block, each with a person’s notes on it. With neither, what each file is and how many blocks it holds. outline lists the addresses.
Arguments:
path(string): A .vzk file, such as pages/index.vzk, to describe its blocks. Omit for a line on every file.address(string): One block’s address from outline, such as pages/index.vzk#hero. Not with path.ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.manifest(boolean): With path or address: also answer the facts under the sentences as data, under facts. Default false.
read_block
Section titled “read_block”Read one block of a file. Scope site:read, read-only.
The text of one block of a vzk file, named by its address from outline (pages/index.vzk#hero), at a branch or a commit (default main), with the commit read, which write_block takes as base, and under notes what a person noted on the block.
Arguments:
address(string, required): The block’s address from outline: its file, # and its id, such as pages/index.vzk#hero.ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.
Show the history of the site’s code. Scope site:read, read-only.
The commits on a branch (default main), newest first, with who made each and a preview URL; with path, only the commits that changed that file. revert takes a commit id from here.
Arguments:
ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.path(string): Only the commits that changed this file.limit(integer): How many commits. Default and most 50.
Compare two versions of the site’s code. Scope site:read, read-only.
The files that differ between two branches or commits (from defaults
to main), each added, modified or deleted, with its text before and
after. diff to a branch is what merge_branch would put live. Where
the site’s tables are files, tables says what that would do to
them, and which steps wait for the owner.
Arguments:
to(string, required): The branch or commit to compare with from.from(string): A branch name from list_branches, or a commit id from log. Defaults to main.paths(array of string): Only these files.
Branches
Section titled “Branches”list_branches
Section titled “list_branches”List the site’s branches. Scope site:read, read-only.
Every branch of the site’s code with its head commit, how many commits it is ahead of and behind main, and a preview URL. main is what the public site serves. Read guide vzk/authoring.
Takes nothing beyond tenant_id.
create_branch
Section titled “create_branch”Create a branch. Scope site:write, writes.
Starts a branch of the site’s code, from main or from another branch or a commit. Write to it with write_files or edit_file; visitors see nothing until merge_branch. Read guide vzk/authoring.
Arguments:
name(string, required): Lowercase segments joined by slashes, such as agent/opening-hours.from(string): A branch or a commit id to start from. Defaults to main.note(string): One sentence, in the customer’s words, kept with the commit.
write_files
Section titled “write_files”Change files on a branch. Scope site:write, writes.
Writes, deletes or moves up to 50 files on a branch as one commit, checked first: a file the compiler refuses refuses the whole commit. A .vzk file is fixed and put in canonical form as it is written, and the answer says what changed. Never writes main; visitors see it after merge_branch. Read guide vzk/authoring and describe_vocabulary topic layout.
Arguments:
branch(string, required): The branch to write, from create_branch. main is never written directly.files(array of object, required): Each file with exactly one of content, delete or move_to.path(string, required): The file, such as pages/about.vzk.content(string): The whole new text of the file.delete(boolean): true to delete the file.move_to(string): A new path for the file, its text unchanged.
message(string): What the change is, in a line. Defaults to naming the files.base(string): The commit you read the files at. A file changed on the branch since then is refused, so another writer’s change is never overwritten.note(string): One sentence, in the customer’s words, kept with the commit.
edit_file
Section titled “edit_file”Change one passage of a file. Scope site:write, writes.
Changes one passage of one file on a branch and leaves the rest as it
is, as one commit checked like write_files. find is copied exactly
from read_files and must occur exactly once, or nothing is written.
A .vzk file is fixed and put in canonical form as it is written, and
the answer says what changed.
Arguments:
branch(string, required): The branch to write, from create_branch. main is never written directly.path(string, required): The file, such as pages/index.vzk.find(string, required): Exact text from the file, whitespace included. Must occur once.replace(string, required): What takes its place, taken literally. An empty string deletes it.message(string): What the change is, in a line. Defaults to naming the files.base(string): The commit you read the files at. A file changed on the branch since then is refused, so another writer’s change is never overwritten.note(string): One sentence, in the customer’s words, kept with the commit.
write_block
Section titled “write_block”Change one block of a file. Scope site:write, writes.
Replaces one block of a vzk file on a branch with new text and leaves the rest of the file as it is, as one commit checked like write_files. Read the block with read_block first. A block that shares a line with other markup is refused: change it with edit_file. The file is fixed and put in canonical form as it is written, and the answer says what changed.
Arguments:
branch(string, required): The branch to write, from create_branch. main is never written directly.address(string, required): The block’s address from outline: its file, # and its id, such as pages/index.vzk#hero.content(string, required): The block’s whole new text, taken literally, as read_block answers it.message(string): What the change is, in a line. Defaults to naming the files.base(string): The commit you read the files at. A file changed on the branch since then is refused, so another writer’s change is never overwritten.note(string): One sentence, in the customer’s words, kept with the commit.
edit_block
Section titled “edit_block”Move, copy, rename, remove, wrap, extract or add a block. Scope site:write, writes.
Moves (within its file or to another), copies, renames, removes or wraps one block of a vzk file on a branch by its address from outline, makes it a component or puts a component back, or adds new markup at a place, without sending the file. One commit, checked like write_files, that may change several files. To undo it, revert to the answer’s parent with its paths. guide vzk/authoring shows each operation.
Arguments:
branch(string, required): The branch to write, from create_branch. main is never written directly.operation(string, one ofdelete,duplicate,rename,move,extract,inline,insert,wrap, required): What to do: every operation but insert takes the block’s address, move and insert a place, insert and wrap markup, rename an id, extract a name.address(string): The block’s address from outline: its file, # and its id, such as pages/index.vzk#hero. Every operation but insert.markup(string): insert: the element or elements to add. wrap: one element with nothing in it, such as <div class=“band”></div>, to put around the block.id(string): duplicate: the copy’s id. Omit it for the next free name. rename: the block’s new id.name(string): extract: the component’s name, a capital then letters and digits, such as Hero. It is written to components/<name>.vzk.before(string): move, insert: the address of the block it goes before, in this file or another.after(string): move, insert: the address of the block it goes after.into(string): move, insert: the address of the block it goes inside, at its end.end(string): move, insert: the path of the file whose markup it goes at the end of.message(string): What the change is, in a line. Defaults to naming the files.base(string): The commit you read the files at. A file changed on the branch since then is refused, so another writer’s change is never overwritten.note(string): One sentence, in the customer’s words, kept with the commit.
revert
Section titled “revert”Put files back as a commit had them. Scope site:write, writes.
Writes one commit on a branch that puts files (path, or up to 50 paths; without either, every file) back as they were at a commit. A file that commit did not have is deleted. Visitors see it after merge_branch. guide vzk/authoring explains undoing a change.
Arguments:
branch(string, required): The branch to write, from create_branch. main is never written directly.to(string, required): The commit id to go back to, from log or a write’s parent.path(string): Only this file. Omit it and paths to put back every file.paths(array of string): Only these files, put back together in one commit.note(string): One sentence, in the customer’s words, kept with the commit.
update_branch
Section titled “update_branch”Bring a branch up to date with main. Scope site:write, writes.
Replays a branch’s commits on top of main so merge_branch can put it live. A file changed on both in the same place refuses the update, handing back its text at the fork, on main and on the branch; retry with resolutions. Read guide vzk/authoring.
Arguments:
branch(string, required): The branch to write, from create_branch. main is never written directly.resolutions(object): For each conflicting file, its whole resolved text, or null to delete it.note(string): One sentence, in the customer’s words, kept with the commit.
delete_branch
Section titled “delete_branch”Delete a branch. Scope site:write, writes, destructive.
Deletes a branch and whatever it holds that was never merged. main cannot be deleted, and the live site is not touched.
Arguments:
name(string, required): The branch, from list_branches.
Publishing
Section titled “Publishing”run_tests
Section titled “run_tests”Play a site’s scenarios. Scope site:read, read-only.
Plays the scenarios in a branch’s or a commit’s tests/<name>.test.ts files (default main) with stand-in visitors and rows of their own; the site’s rows are never touched. Answers each scenario by name, and for one that fails its line, what did not hold and what the page showed. merge_branch is refused while one fails. Read guide vzk/tests.
Arguments:
ref(string): A branch name from list_branches, or a commit id from log. Defaults to main.
merge_branch
Section titled “merge_branch”Put a branch live. Scope site:write, writes, destructive.
Publishes a branch: main moves to it and visitors see its files at once. Refused when main has moved since the branch was updated (call update_branch first), and while one of its scenarios fails (run_tests). Where the site’s tables are files, merging changes them too, and a branch with a step that waits for the owner is refused: they merge it on their Branches screen. The branch is deleted afterwards unless keep_branch. Undo with revert on a new branch.
Arguments:
branch(string, required): The branch to put live, from list_branches.keep_branch(boolean): Keep the branch after the merge. Default false.note(string): One sentence, in the customer’s words, kept with the commit.
Languages
Section titled “Languages”set_site_languages
Section titled “set_site_languages”Say which languages a site speaks. Scope site:write, writes.
Declares the languages a site serves. This is the first call of
building a multilingual site, and nothing about languages works until
it has been made: no path prefix, no switcher, no lang attribute,
no hreflang, and no locales/ catalog is read.
This takes effect at once: it is a site setting, not a draft, so the
prefixed addresses go live whether or not the pages are translated.
Send locales: [] to go back to one language. Read
vzk/languages first.
Arguments:
default(string): The language served on the site’s plain paths, as a tag like “en” or “pt-br”. The one language with no prefix of its own.locales(array of string): Every other language the site speaks, as tags: [ “uk”, “ru” ]. This is the order a switcher offers them in, after the default. Listing the default here too is fine and means the same thing. An empty list un-declares every language.
update_site_meta
Section titled “update_site_meta”Set the site’s default meta tags. Scope site:write, writes.
Sets what the site’s <head> says by default: the description a
search result shows, who made it, the colour a phone browser paints
its chrome, and whether search engines should index it at all. Every
page of the site uses these unless that page says something of its
own in its own head.
Live at once. This is a site setting, not a file: there is no
branch, nothing to preview and nothing to merge, so a site-wide
noindex hides the whole site from search engines the moment it is
sent.
Arguments:
description(string): One or two sentences about the page, shown under its title in a search result and on a shared link. Set at site level it describes the whole site.keywords(string): Comma-separated words. Search engines have long ignored these; they are here because some other tools still read them.noindex(boolean): Ask search engines to leave this out of their index. Set at site level it hides the whole site, which is for a site that is not ready to be found.author(string): Who made the site — usually the owner’s own name.theme_color(string): The colour a phone browser paints its chrome with, as a CSS colour (“#101010”).twitter(string): The site’s X handle, with the @ (“@mirahalden”). It is what an X card credits.page_fades(boolean): Fade from one page of the site into the next instead of cutting. Off unless set, and a page’s own value overrides the site’s.morph_refreshes(boolean): Redraw a page that answers with itself, such as a form’s thanks, in place and at the same scroll position. Off unless set, and it asks things of the site’s own scripts (vzk/javascript).translations(object): The same fields in the site’s other languages, keyed by language tag: { “uk”: { “description”: “…” } }. Merged per language and key by key inside it. Words only — an author and a theme colour are the same in every language.
Tables
Section titled “Tables”create_table
Section titled “create_table”Add a table to this site. Scope site:write, writes.
Gives the site a table of its own: a named set of fields, and somewhere
to put the rows. This is how a contact form gets somewhere to send
what a visitor types. It writes tables/<handle>.json on branch, and
merge_branch makes the table. Read vzk/tables first.
A reserved handle must keep what its dashboard screen reads, and may add anything else:
The owner’s Enquiries screen reads enquiries. It must keep at least one field of the site’s choice, and it must stay readable_by: owner (it holds what strangers send).
The owner’s Posts screen reads posts. It must keep title (text, what the post is called, in the tab and on a shared link) and body (markdown, the post itself), and it must stay readable_by: public (its records are pages of the site). By default, rows wait for a published_at date; publication is configurable.
The owner’s Portfolio screen reads portfolio. It must keep title (text, the item’s name), summary (long_text, a line about the item), cover (picture, the item’s picture), body (markdown, the item’s story), and position (number, its place in the owner’s order), and it must stay readable_by: public (its records are pages of the site). By default, rows wait for a published_at date; publication is configurable.
Arguments:
handle(string, required): A lowercase handle, such as “enquiries”. This is what a<form table="…">names and what the submission path carries.vizitkais the platform’s own and is refused; the reserved handles in this tool’s description are yours to use and must keep their screen’s shape.name(string): What the owner sees this table called on their dashboard: at most 100 characters, with no line break or other control character.fields(array of object, required): The shape of one row: a list of fields, in the order a form should ask them, at most 100 of them.name(string, required): A lowercase handle, such as “email” or “phone_number”, and neverid,slug,urlorupdated_at, which every row answers itself. A form input is namedfields[<name>].type(string, one oftext,long_text,markdown,email,phone,url,number,date,datetime,boolean,choice,reference,references,picture, required): What this field holds, and what a submitted value is checked against.label(string): What a person reads beside the input: at most 100 characters, never empty or white space alone, and no line break or other control character.required(boolean): Whether a row is refused without it. Default false.options(array of string): For achoicefield: the values it may hold, each once, at most 200 of them and each at most 500 characters, with no white space at either end and no line break or other control character.multiple(boolean): For achoicefield: whether a row holds a list of its options rather than one. Narrowed withfilter(p => p.<name>.includes("…")), never sortable, and plays no role. Default false.table(string): For areferenceorreferencesfield: the handle of this site’s table whose rows it names, which may be this one.max(integer): For areferencesfield: the most rows one row’s list may name, from 1 to 500. A write naming more is refused. Default 500.fill(string, one ofnow,visitor): For adatetimefield:nowsets it to the time a row is added, whoever adds it. For areferencetopeople, on a site whose visitors sign in:visitorsets it to the signed-in visitor who adds the row, and leaves it empty for anybody else. No write sets or changes such a field: leave it out of a row’s values, and a form has no control for it.includes(string, one ofvisitor): For areferencesfield topeople, on a site whose visitors sign in:visitorputs the signed-in visitor who adds a row in its list. The rest of the list is the writer’s to set.filterable(boolean): Whether a page may narrow or search a listing on this field, withtables.<handle>.filter(p => p.<name> == "…")orfilter(p => p.<name>.includes(query.q)). Areferenceis compared with a row,p.<name> == row, and areferencesis askedp.<name>.includes(row). Default false. Which comparisons it then answers is whatdescribe_vocabulary topic=fieldslists beside its type.role(string, one oftitle,body,language,summary,cover): What the platform itself reads this field for, if anything. One field per role, and a table that names none for a role falls back to the field literally called that. What each role buys is indescribe_vocabulary topic=fields. Most fields have none.sortable(boolean): Whether a page may read a listing in this field’s own order, withtables.<handle>.sortBy(p => p.<name>, "desc"). Default false, and separate fromfilterable. Only on a type whose values sit in an order, whichdescribe_vocabulary topic=fieldssays beside each one, so not on aboolean.was(string): The name this field had on main, so merging renames it and every row keeps its value.default: What merging gives each row that has no value for this field, as a row would hold it. Needed to make a field required on a table that has rows.replace(object): On achoice: for each option taken away, the option merging puts in its place in every row.
publication(object or null): Which rows may appear publicly. Set field to null for all rows, or name a declared date field (today or earlier) or boolean field (true). Null restores the default: posts and portfolio use published_at; other tables show all rows. Changes are live at once without editing rows. Table read access still applies.field(string or null, required)
keep(string or null): How long the table keeps a row, as a whole number of days from 1 to 3650: “90 days” or “1 day”. Rows older than that, counted from the day each was added, are removed from the table once a day, never sooner than a day after the setting is saved or changed, and cannot be brought back from the dashboard or by an agent, so ask the owner before setting it. Taken only for a table that isreadable_by: public: the owner sets it for any other on their dashboard. Null keeps every row, which is the default.writable_by(string, one ofowner,public): Who may add a row.publicis what lets a visitor submit a form. Defaultowner.readable_by(string, one ofowner,public): Who may read a row.ownerkeeps it off the site entirely and is the right answer for anything a stranger sends.publiclets a page list the rows, and is what a table needs before it can have a page of its own (pages/<path>/[slug].vzk). Defaultowner.branch(string): The branch to write tables/<handle>.json on, from create_branch.message(string): What the change is, in a line. Defaults to naming the files.
update_table
Section titled “update_table”Change a table. Scope site:write, writes, destructive.
Changes a table this site already has: what it collects, what it is called, who may write and read it, which rows are published, and how long it keeps its rows.
Every change but publication is written into tables/<handle>.json
on branch, and nothing changes until merge_branch: merging then
moves the rows to the new shape, and the answer’s tables says how.
fields is sent whole and takes effect at once: the form on the
site starts asking the new questions on its next render. Rows already
stored are not touched — nothing migrates and nothing is lost, so a
field you drop stops being read while its values stay in the rows that
have them, and a field you add is simply empty on everything written
before it.
code_access is what this site’s code, the functions its forms run,
may do to the table: count its rows, insert a row. A page that
shows a count, or changes with it, tells every visitor how many rows
the table holds. Code cannot add rows to a table visitors can read.
read, update and delete go only into a table’s file, where the
site has them, and the merge then waits for a person to approve it.
Take a field or a grant out of the site’s live pages before taking it from the table. While a live page still uses one that is gone, every form on the site stops taking submissions until the pages are changed.
A reserved table keeps the contract get_site states on it, and a
definition that breaks it is refused naming what reads it. Read
vzk/tables first.
Arguments:
handle(string, required): The table’s handle, as get_site lists it.fields(array of object): The whole shape of one row, replacing what is there, at most 100 fields. Live at once, and rows already stored are untouched. A reserved table has to keep the shape its dashboard screen needs, and a role dropped here is a role the platform reads off no field of this table.name(string, required): A lowercase handle, such as “email” or “phone_number”, and neverid,slug,urlorupdated_at, which every row answers itself. A form input is namedfields[<name>].type(string, one oftext,long_text,markdown,email,phone,url,number,date,datetime,boolean,choice,reference,references,picture, required): What this field holds, and what a submitted value is checked against.label(string): What a person reads beside the input: at most 100 characters, never empty or white space alone, and no line break or other control character.required(boolean): Whether a row is refused without it. Default false.options(array of string): For achoicefield: the values it may hold, each once, at most 200 of them and each at most 500 characters, with no white space at either end and no line break or other control character.multiple(boolean): For achoicefield: whether a row holds a list of its options rather than one. Narrowed withfilter(p => p.<name>.includes("…")), never sortable, and plays no role. Default false.table(string): For areferenceorreferencesfield: the handle of this site’s table whose rows it names, which may be this one.max(integer): For areferencesfield: the most rows one row’s list may name, from 1 to 500. A write naming more is refused. Default 500.fill(string, one ofnow,visitor): For adatetimefield:nowsets it to the time a row is added, whoever adds it. For areferencetopeople, on a site whose visitors sign in:visitorsets it to the signed-in visitor who adds the row, and leaves it empty for anybody else. No write sets or changes such a field: leave it out of a row’s values, and a form has no control for it.includes(string, one ofvisitor): For areferencesfield topeople, on a site whose visitors sign in:visitorputs the signed-in visitor who adds a row in its list. The rest of the list is the writer’s to set.filterable(boolean): Whether a page may narrow or search a listing on this field, withtables.<handle>.filter(p => p.<name> == "…")orfilter(p => p.<name>.includes(query.q)). Areferenceis compared with a row,p.<name> == row, and areferencesis askedp.<name>.includes(row). Default false. Which comparisons it then answers is whatdescribe_vocabulary topic=fieldslists beside its type.role(string, one oftitle,body,language,summary,cover): What the platform itself reads this field for, if anything. One field per role, and a table that names none for a role falls back to the field literally called that. What each role buys is indescribe_vocabulary topic=fields. Most fields have none.sortable(boolean): Whether a page may read a listing in this field’s own order, withtables.<handle>.sortBy(p => p.<name>, "desc"). Default false, and separate fromfilterable. Only on a type whose values sit in an order, whichdescribe_vocabulary topic=fieldssays beside each one, so not on aboolean.was(string): The name this field had on main, so merging renames it and every row keeps its value.default: What merging gives each row that has no value for this field, as a row would hold it. Needed to make a field required on a table that has rows.replace(object): On achoice: for each option taken away, the option merging puts in its place in every row.
name(string): What the owner sees this table called: at most 100 characters, with no line break or other control character.publication(object or null): Which rows may appear publicly. Set field to null for all rows, or name a declared date field (today or earlier) or boolean field (true). Null restores the default: posts and portfolio use published_at; other tables show all rows. Changes are live at once without editing rows. Table read access still applies.field(string or null, required)
keep(string or null): How long the table keeps a row, as a whole number of days from 1 to 3650: “90 days” or “1 day”. Rows older than that, counted from the day each was added, are removed from the table once a day, never sooner than a day after the setting is saved or changed, and cannot be brought back from the dashboard or by an agent, so ask the owner before setting it. Taken only for a table that isreadable_by: public: the owner sets it for any other on their dashboard. Null keeps every row, which is the default.writable_by(string, one ofowner,public): Who may add a row. Takes effect at once.readable_by(string, one ofowner,public): Who may read a row. Takes effect at once.owneris refused while the table has a page of its own: delete its file on a branch and merge it first, and every row’s address goes with it, so say so to the owner before doing it.code_access(array of string): What this site’s code may do to the table, sent whole and replacing what is there. Takes effect at once. A count on a page tells visitors how many rows the table holds. An empty list takes every grant away.branch(string): Needed for any change butpublication: the branch to write tables/<handle>.json on. Left out on a frozen site, where taking grants away goes live at once.message(string): What the change is, in a line. Defaults to naming the files.
Records
Section titled “Records”list_records
Section titled “list_records”List a table’s rows. Scope site:read, read-only.
The newest 50 rows of one of this site’s tables, newest first: its
tenant_record_id, its slug, its title, whether it is published, and
where it answers. This is how you find the post you are about to edit
or publish. An older row is not missing just because it is not here.
Arguments:
handle(string, required): Public table handle from get_site.
get_record
Section titled “get_record”Read one row. Scope site:read, read-only.
One row whole: every value it holds, in the order its table declares
them, plus its tenant_record_id, its slug, whether it is published,
and the address it answers at. list_records is how you find the slug.
Arguments:
handle(string, required): Public table handle from get_site.slug(string, required): Row slug from list_records: its address’s last segment.language(string): Row language, where rows share a slug.
create_record
Section titled “create_record”Write a post. Scope site:write, writes.
Writes one row into a table this site owns. A post is a row, not a
page: a blog is one posts table, the page every post renders
through, a row per post, and a page at /blog listing them. A page
each would put every post in the owner’s Pages sidebar and in every
nav that loops site.pages, with no listing and no shared address.
Publication follows the table’s rule from get_site: all rows, a date
that has come, or a boolean that is true. A new row
starts the table’s active workflows, the same as a visitor’s
submission does. Read vzk/tables first.
Arguments:
handle(string, required): Public table handle from get_site.values(object, required): The row’s own values, keyed by the field names its table declares: { “title”: “How I light a winter wedding”, “body”: “…markdown…” }. Checked against the definition and cut down to it, so a key the table does not name is dropped, a value of another type is cast to what the field holds (5 under a text field is stored as “5”), and one the type refuses even then comes back as a sentence naming the field. A field pointing at rows takes thetenant_record_idlist_records shows for each: 14, or [3, 7] where it holds a list.slug(string): Where this row answers, as the last segment of its address. Leave it out and the title is slugged.
update_record
Section titled “update_record”Rewrite a row. Scope site:write, writes, destructive.
Replaces what one row holds. values is sent whole, so a field
you leave out is dropped: read the row with get_record, change the
part you mean to change, and send it all back. Sending only a title
is how a post loses its body.
There is no draft. An edit to a published row is on the site as
this returns; replaced in the answer is what to send back if it was
wrong. The table’s publication rule decides whether the changed row
stays public: all rows, a date that has come, or a boolean that is true.
Leaving a configured publication field out takes the row off the site.
There is no rename: the slug is
the row’s address and nothing writes a redirect.
Arguments:
handle(string, required): Public table handle from get_site.slug(string, required): Row slug from list_records: its address’s last segment.language(string): Row language, where rows share a slug.values(object, required): The row’s own values, keyed by the field names its table declares: { “title”: “How I light a winter wedding”, “body”: “…markdown…” }. Checked against the definition and cut down to it, so a key the table does not name is dropped, a value of another type is cast to what the field holds (5 under a text field is stored as “5”), and one the type refuses even then comes back as a sentence naming the field. A field pointing at rows takes thetenant_record_idlist_records shows for each: 14, or [3, 7] where it holds a list. Replaces what the row holds, so send the whole row back.
delete_record
Section titled “delete_record”Delete a row. Scope site:write, writes, destructive.
Deletes one row. There is no undo through this connection. Read it
with get_record first if there is any chance it is wanted.
Arguments:
handle(string, required): Public table handle from get_site.slug(string, required): Row slug from list_records: its address’s last segment.language(string): Row language, where rows share a slug.
Platform
Section titled “Platform”list_feature_requests
Section titled “list_feature_requests”What this site has already asked the team for. Scope site:read, read-only.
Lists the feature requests this site has filed with the Vizitka team —
newest first, each with its status. Check it before request_feature:
a gap that is already pending or filed does not need filing again.
Takes nothing beyond tenant_id.
request_feature
Section titled “request_feature”File a feature request with the Vizitka team. Scope site:read, writes.
Files a feature request with the Vizitka platform team when the customer asks for a capability the format cannot express. It records the request and opens an issue in the platform’s own tracker; it does not read or change this website.
Arguments:
title(string, required): One line naming the missing capability, such as “Video embeds on a page”.request(string, required): What the customer asked for, in their words.limitation(string, required): What capability the platform could not express.workaround(string): What you built instead with today’s vocabulary, if anything.tags(array of string, required): Where the gap is: vocabulary (a missing class, value or template capability), styling (the stylesheet, its tokens or component classes), layout (an arrangement the primitives cannot express), content (text and content features), media (images, video, galleries, uploads), pages (page management and navigation), forms (contact forms and other input), bookings (scheduling and appointments), payments (prices, checkout, invoicing), integrations (third-party services and embeds), seo (titles, descriptions, search visibility), i18n (languages and translation), other (anything the rest do not cover).