PublicViews

Guide

Publishing a page, screen by screen

Six screens, in the order the product puts them in, and what each one actually decides. Read it once and the shape stops being surprising: almost every rule in here is a consequence of the same idea, which is that nothing is exposed until you expose it.

What you are building

Three words, and the whole product is the relationship between them.

  • A page (the product calls it a view) is one published URL. It carries where its records come from, the set of attributes a viewer can see, the smaller set a viewer can propose changes to, and an access policy.
  • Its records are an Attio list or object, optionally narrowed: by one of your Attio saved views, or by conditions you build here. You choose that once, on the screen that creates the page, and you can change it afterwards.
  • A viewer is whoever opens the link. They have no account with us and no Attio seat.

Underneath, the records half of a page is a row of its own (a source) and the product still uses that word on one screen, the one you are sent to when something about the syncing has broken. You never create one: making a page makes it.

Nothing is public at any point before you press Publish, including everything on this page up to step six. The screens say so where you would reasonably be nervous.

The order of the screens

Inside a view, the tabs run left to right in the order you work through them, and a step bar above them shows which of the four setup steps are done. It is a wizard drawn as a tab bar, so you can move around it freely; a step is ticked when its work is done, not when you have visited it.

ScreenWhat you decide thereWhen
Settings → AttioWhich Attio workspace we may read.Once per workspace
New pageWhich list or object, and which of its records: all of them, or an Attio saved view.Once per page
FieldsWhich attributes a viewer sees, in what order, under what names, and which of them a viewer may propose a change to.Required
Who can open itThe locks on the link: public, password, allowlist, expiry. Also whether viewers may edit at all.Arrives configured
Row scopingWhich rows each individual viewer sees, matched on their confirmed address.Optional
Preview & publishThe page exactly as a viewer gets it, the manifest of what is and is not exposed, and the button.Required
EditsThe queue of changes viewers have proposed, waiting for you.After it is live
AnalyticsWho opened it and when.After it is live

Row scoping is never ticked, on purpose: it is optional on every plan, and a view with no scoping rule is a finished view. Edits and Analytics sit outside the wizard because neither is setup. One configures what happens after records reach somebody, and the other has nothing to show until they do.

1. Connect the workspace

Sign up, then connect Attio over OAuth. We read the lists and objects your own Attio account can see, so a view can never contain something you could not already open yourself. Connecting publishes nothing.

Attio’s consent screen will ask for write access. Expect it, and do not read anything into it. Attio fixes an app’s scopes at registration and offers no way to narrow them per install, so every publisher consents to the same set whether or not any view they ever build is editable. What decides whether we write is our own layer: editing is off on a new view, and turning it on takes four separate conditions, described below. The security page has the longer version, and the connect screen says it in the same words.

If the connection later stops working, your dashboard leads with it: the workspace, when Attio stopped accepting the credential, and how many of your pages are dark because of it. Reconnecting restores them, on Settings → Attio. Nothing is deleted in the meantime.

2. Choose the records, and the page is made

One screen, at Pages → New page, and two real decisions. Pressing the button creates the page as a draft. It publishes nothing.

A list or an object

Pick whichever matches how you already think. Both are offered as a plain list of what that workspace holds, with no record counts beside them. Counting every candidate would mean paging every list in your workspace against an Attio budget that is shared across the whole of it, before you have chosen anything. The number arrives on the first sync, and the screen says so where the number would have been.

Which of its records: everything, or an Attio saved view

The first option is everything in this list, and it is offered at the same weight as the saved views underneath it rather than as a fallback. Then your Attio saved views on that target, by name.

Here is the one disappointment in the product, and it is not one we can engineer around. Attio’s API returns a saved view’s name and nothing else, not its filter. So we cannot promise that a view named for one client narrows anything: in the workspace we probed, three of six saved views returned their whole object. The screen says exactly that, above the choice rather than in a footnote after it.

What we do instead is measure it. The first sync checks whether the saved view returns the entire list, and if it does the page is paused before anybody can open it and you are asked whether you meant to publish all of them. That pause is designed; it is not the product going wrong.

A title, which is already filled in

It follows the two choices above (the saved view’s name, or the list’s) until you type in the field, at which point it stops following and is yours. Your viewer sees it at the top of the page.

Press Create this page and you land on its Fields tab. Behind the one request: we read that target’s attribute schema from Attio and store it, record the membership rule you chose, create the draft page with its access policy, and ask for the first full read of the records. Nothing is written to Attio, and nothing is public.

Narrowing it further: the condition builder

If neither everything nor a saved view is the slice you want, you can build the conditions yourself: attributes, operators and values, grouped with all and any. This one is a paid capability. The free plan carries the other two membership rules and not this one, and the screen names the plan that has it rather than hiding the controls.

It lives on the page’s data and sync screen, which you reach by clicking what a page reads on the Views list, and which the publish screen links to directly whenever something about the syncing is wrong. The same screen holds the history of every sync and the Resume control.

Watch the negated operators. In Attio, is not also matches records where the field is empty, so “stage is not Lost” publishes every record with no stage set. The builder says so next to the operator, and the live count beside it is the fastest way to notice.

Saving is what verifies it. There is no separate verify button. Pressing Save compiles the conditions, runs them against Attio, and reports the count that came back, which also becomes the baseline for change alerts. A filter that has never run successfully cannot be attached to a live page; that is a refusal at publish, not a warning.

Saving with the conditions removed is allowed and says what it did: nothing was sent to Attio, because there was nothing to run, and the page now covers every record in the list or object. That is a legitimate configuration (a public directory is exactly this), so it is not treated as a fault. It is held at the publish screen instead, where you confirm it per publish rather than once and forever.

If your plan later stops carrying the builder, a filter you already saved is never cleared and never converted. A cleared filter would publish the whole object, silently, on a page a client is already reading. It goes on selecting exactly what it selected before; what you lose is the ability to change it, and to publish or resume that page until the plan carries it again.

3. Fields: what a viewer sees

The screen is split in two, because the visible set and the hidden set are different problems. Visible is short and ordered: it is the column list of the published page, so you drag it into the order you want. Hidden is long and searched: a catalogue with a search box and filters, because nobody orders forty-five attributes, they look one up.

Everything starts in the hidden half. Press Show on the ones a viewer should see. What you do not show is not merely absent from the page: with a small and stated set of exceptions (an attribute used to sort the page, group a board, label a linked record or decide which viewer sees which rows) it stays out of the cache entirely, so it is not on our servers to leak. The security page has the full table, including the two kinds we hold and never display.

Renaming and ordering

Every visible field takes a column heading of your choosing, so an internal slug does not go in front of a client. arr_2026_committed becomes Committed. Any field whose contents would publish something about a person is flagged amber, inline with the name, at the moment you make it visible rather than afterwards in the preview.

When a column does not appear yet

Making a new field visible means we now need an attribute we were not previously reading, so the cache has the column and not its values. The screen says which field is waiting and offers to start the re-read. Your published page keeps serving the columns it already has throughout, and the publish gate holds a new publish until the re-read finishes. Neither is a fault; it is the product refusing to show a half-filled column.

Marking a field editable

The tick is here, on the field. Whether it does anything is decided by four conditions, and the Access tab shows them as a numbered checklist so you can see all four at once rather than meeting them one at a time:

  1. Your plan includes viewer edits. Where it does not, the tick is disabled rather than hidden, and the screen names the plan that has it.
  2. The page can tell who a viewer is. An edit is attributed to a person, so the view needs an email or domain allowlist. A password does not count because it proves someone knows the password, not who they are.
  3. At least one field is ticked editable. Which is this screen.
  4. Viewer edits are switched on for the page. Which is the Access tab.

Ticking fields before the rest is a perfectly good order of work, and the product allows it: the ticks are stored and start working the moment the other conditions are met. What it will not do is let you leave that state without knowing. A page with fields ticked and the switch off says so, on this screen, in a neutral line rather than a warning, because it is the normal middle of a two-tab job. The attribute type support page has the exact split of which types can ever be editable and why each of the others cannot.

4. Who can open it

Four locks. The single most important sentence on the screen is that they combine with AND: a viewer must satisfy every one that is switched on, not any one of them. A correct password does not clear the allowlist, and an allowlisted address does not clear the password. A rail down the side of the screen states the chain in the order a viewer meets it, so the answer to “who can open this right now” is never something you have to assemble in your head.

The default is a public link

A view is created with an access policy already on it, and that policy is anyone with the link. This is why the setup bar shows the access step ticked before you have opened it: the step is done in the sense that the view has a policy and would open for somebody, which is the failure the tick exists to catch. It is not done in the sense of being the policy you want.

So treat this tab as a decision you have to make rather than a step you can skip. With the public link on and nothing else on, the URL is the only protection the page has. The slug is unguessable, and an unguessable string in somebody’s forwarded mail is still a string anyone can paste. The screen colours that state as the fact it is, on this tab and on the views list.

The other three

  • Password. A shared secret, set per view. It proves possession and nothing about who is holding it, which is why it never satisfies the allowlist.
  • Email or domain allowlist. A viewer enters an address; only listed addresses and domains are ever emailed a link. Everyone else gets the identical “check your email” screen and no mail, so the gate never confirms who is on the list. Domains match exactly. A rule for a company’s domain does not admit its subdomains.
  • Expiry. On a date, after a number of opens, or both. It is checked before any password or allowlist, so a dead link never asks for a credential. A date in the past closes a link immediately, which is the quickest way to shut one you have already sent.

Which of these your plan includes is shown on the tab: a mode you do not have renders disabled with the plan that carries it named beside it, rather than being hidden. The pricing page has the full split.

Turning on viewer edits changes who can read

This is the consequence to understand before you choose it, and it surprises people. Proposed edits require an allowlist, and an allowlist challenges everyone. Once one is set, every visitor is asked for an address and has to confirm it before they see a single row, including on a link you had open to anyone holding it. There is no setting that asks for an address only from the people who want to edit. Switching edits on is therefore a change to the read gate as well, and the confirmation step says so before you commit.

The confirmation is also honest about the concurrency check, which is worth reading once. When you approve an edit we re-read that one attribute from Attio and compare it to what the viewer was looking at; if it moved, we mark the edit stale and write nothing. That check narrows the window to seconds and is not a lock, because Attio has no version, no ETag and no conditional write. A change made in Attio inside that window can still be overwritten, and we keep the value we replaced so you can put it back.

Changing anything on this tab signs out every viewer reading the page right now, so nobody keeps a session granted under the old rules. It does not re-sync anything and does not clear the cached rows.

5. Row scoping (optional)

Everything above decides who gets the page. Row scoping decides which rows of it they get, by matching one attribute on each record against the address a viewer confirmed. One link, and each client sees their own records.

Two properties follow from it being built on a confirmed address. Email verification is forced on and stays on while scoping is enabled. A scoping rule matches a verified address or it matches nothing. And a viewer who has verified nothing sees zero rows: missing identity never widens access. The screen shows both outcomes side by side rather than asserting them.

There is deliberately no domain mode here. Scoping means “this one person”; “everyone at this company” is what the domain allowlist is for, one tab back.

6. Preview and publish

The last screen is two panes. On the left is the page your viewer will get. It is not a mock of it: it is the published page’s own layout component, on the published page’s own data, so the only way for it to differ from what you send would be for us to have written a second renderer, and we did not. Withheld columns are drawn inside the table as solid blocks, so you see the shape of what you are holding back instead of reading a list of names.

On the right is the manifest: what a viewer will see, what is sensitive, and what is withheld, in that order, above the button. Read the left pane as the person you are about to send it to rather than as the person who configured it. That is the whole trick, and it is why this screen is the last one before publish rather than a settings tab.

If the button is disabled

Publishing is gated, and the gate collects every reason at once rather than making you fix them one at a time. Each refusal renders as a headline, the reason, and the control that resolves it, with its code printed underneath. Two of them are confirmable, and the confirmation is read from the press you are making now, never remembered from a previous visit.

CodeWhat it meansWhat clears it
CONNECTION_UNUSABLEWe can no longer use the stored Attio credential for this workspace.Reconnect the workspace in Settings → Attio. Nothing you configured is lost.
SOURCE_UNVERIFIEDThis source's filter has never run against Attio, so we have no evidence it works.Open the data and sync screen — the panel links straight to it — and save the filter. Saving is what runs it.
SOURCE_BROKENAttio rejected the filter, or the source is marked broken.Open the filter. The offending condition is marked, with Attio's own reason.
SOURCE_PAUSEDSomebody paused this source, so nothing is refreshing the records behind the page.Open the data and sync screen — the panel links straight to it — and press Resume.
PROJECTION_PENDINGYou made a field visible that we have not read yet, so the column exists and its values do not.Wait for the re-read, or start one if nothing is running. It unlocks itself.
PROJECTION_UNKNOWNWe cannot confirm the cache holds every visible field.Check again. An unknown answer is a refusal here, not a pass.
NO_ACCESS_POLICYThis page has no access policy at all, so every visitor including you would be turned away.Open Who can open it and switch something on.
NO_VISIBLE_FIELDSEvery attribute is hidden, so the page would have no columns.Show at least one field.
UNFILTERED_UNCONFIRMEDThe source has no conditions, so publishing it publishes every record in the list or object.Tick the confirmation, or go and add a condition. Both are offered.
ZERO_MATCHES_UNCONFIRMEDThe filter matches nothing at this moment, so the page would be blank.Tick the confirmation, or fix the filter.

There is no arm of that screen that publishes anyway with a warning. If the button is live, nothing in the list above applies.

What your viewer gets

A page, at a URL, with no account to create. Across the top is a strip stating what they are looking at: whether the page is live, when it last updated, how many of the record’s attributes are being shared out of how many exist, and whether they can change anything. That strip is the product being honest with your client on your behalf, and it omits a fact rather than guessing at one. If we do not know when the page last updated, the segment disappears instead of saying “recently”.

Where you marked a field editable and the other three conditions are met, a viewer can change that cell in place, one field at a time. Nothing they type reaches Attio. The cell reads waiting for approval once it has been sent, and it never reads saved, because there is no version of this product in which a viewer’s change writes straight through. The change queues on your Edits tab beside the value Attio holds now, and you approve it or reject it. Rejecting throws it away and changes nothing.

After it is live

  • Freshness. We cache the records behind a published view rather than calling Attio when someone opens the page, so traffic costs you no Attio rate limit and the page is as current as the last check rather than as current as Attio. How often we check depends on your plan and how many records are behind the page; the intervals are on the pricing page, and every published page carries the time it last updated.
  • Pausing. The kill switch is on the bar above every tab of a view and on the views list, so it is never a navigation away from wherever you were when you realised. Pause is one click with no confirmation, because pause is the safe direction. Resume is the one with the dialog, and it re-runs the publish gates. The button tells you how many open viewer sessions were signed out.
  • The link itself. A view’s slug is minted once and never minted again, so a URL that has been retired can never be handed to a different page later. Your configuration survives a pause; publishing again puts the same page back at the same address.
  • Locked out of your own account. The sign-in form links to a password reset. It answers the same way for an address with an account and one without (“if that address has an account”), because a form that says “no such user” tells a stranger who has an account here.

If the page is empty

In rough order of likelihood, and each of these is visible somewhere in the dashboard rather than something you have to guess at.

  • Nothing has synced yet. Publishing a page is what puts its records on the sync schedule, so a page published a minute ago can be a correct, live, empty page. The data and sync screen says whether a sync has ever run.
  • The filter matches nothing right now. If this were true when you published, you ticked a confirmation saying so. Open the filter; the count under it is live.
  • A negated condition is doing something you did not mean. The same is not trap in the other direction: a condition that excludes everything.
  • Syncing is paused. Nothing refreshes behind a paused page, and the data and sync screen carries the Resume control.
  • The Attio connection needs reconnecting. Connections leads with this and counts how many of your pages are dark.
  • Row scoping is on and the viewer matched no rows. Empty for that person and correct for everybody else. This is the design working: a viewer who has confirmed nothing sees nothing.
  • Your viewer is not describing an empty page at all. A working view with no records says so (“nothing to show yet”), and that is the only screen in the viewer that says anything about the data, because a client staring at a blank table needs to know the page itself is fine. A paused view and an expired link each say what happened. A link that was turned off and a link that never existed share one screen and say nothing more, deliberately, so a stranger cannot use a URL to find out whether it was ever real. If your client reports one of those rather than an empty table, check the view’s state before you check the filter.

The four mistakes worth avoiding

An attribute with an innocent name that is not innocent, such as an internal owner or a margin. A negated filter that quietly includes every record with an empty field. A public link where a domain gate was meant to be, which is the default and therefore the one nobody chose. And switching on viewer edits without noticing that the allowlist it requires now challenges every reader. The first three are all visible in the exposure preview; the fourth is stated at the moment you turn it on.

Anything here wrong, or missing? help@publicviews.app. The answer usually becomes a paragraph on this page.

Publish one real list and see.

The free plan covers one page and does not expire. No card.

Start a workspace