docpin
View as Markdown

Page data

Every DocPin page has a data store: one JSON object, up to 1 MB, kept separately from the page's HTML. The page reads it in the browser. You change it from the API, from an AI app over MCP, or in the DocPin web app, and the page shows the new values without being republished.

Use it for anything that changes more often than the page itself: dashboards, status boards, price lists, scores, schedules, "last updated" banners.

How it fits together

 your script / cron / CI ──PATCH /v1/pages/{id}/data──┐
 Claude or ChatGPT ───────set_page_data (MCP)─────────┤
 DocPin web app ──────────Data tab────────────────────┤
                                                      ▼
                                          page data (JSON, ≤ 1 MB)
                                                      │
                     docpin.data() / docpin.onData() ◀┘  (in the published page)

Read it in the page

DocPin adds a small script to every published page, which provides a global docpin object. You don't include anything yourself.

docpin.data()

Returns a promise for the page's data object ({} if nothing has been set).

<div id="revenue">…</div>
<script>
  docpin.data().then((data) => {
    document.getElementById("revenue").textContent =
      data.revenue == null ? "No data yet" : "$" + data.revenue.toLocaleString();
  });
</script>

After it resolves, docpin.updatedAt holds when the data last changed (ISO 8601), or null.

docpin.onData(callback, { every })

Reads the data now, then re-checks every every seconds (default 30, minimum 10) and calls callback(data) whenever it changed. Checks pause while the tab is hidden. It returns a function that stops checking.

const stop = docpin.onData((data) => render(data), { every: 60 });
// later, if you need to: stop();

Use onData for anything left open on a screen, like a TV dashboard: new data appears without anyone reloading.

Writing pages that use data

Update it from code: the REST API

Base URL: https://api.docpin.app. Authenticate with a workspace API key: Authorization: Bearer dp_…. Workspace owners create keys in the DocPin app under Connections → API keys. You need the page's id, which GET /v1/pages lists and every publish response includes as doc.id.

MethodPathWhat it does
GET/v1/pages/{id}/dataReturns { "data": {…}, "updatedAt": "…" | null }
PATCH/v1/pages/{id}/dataMerges the top-level keys you send. A null value removes that key.
PUT/v1/pages/{id}/dataReplaces all of the page's data with the object you send.

The request body is the JSON object itself, not wrapped. Both writes return the full stored data and its new updatedAt.

curl -X PATCH https://api.docpin.app/v1/pages/$PAGE_ID/data \
  -H "Authorization: Bearer $DOCPIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revenue": 128400, "asOf": "2026-11-06T09:00:00Z", "stale": null}'
{ "data": { "revenue": 128400, "asOf": "2026-11-06T09:00:00Z" }, "updatedAt": "2026-11-06T09:00:02.114Z" }

Prefer PATCH. It only touches the keys you send, so two jobs that each own different keys (say, sales and support numbers) can't overwrite each other. Use PUT when one job owns the whole object.

On a schedule

Any scheduler that can make an HTTPS request works: cron, GitHub Actions, a serverless function, Zapier or Make. For example, a GitHub Actions workflow:

on:
  schedule: [{ cron: "*/15 * * * *" }]
jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - run: |
          REVENUE=$(curl -s https://example.com/internal/revenue)   # your source
          curl -fsS -X PATCH https://api.docpin.app/v1/pages/${{ vars.PAGE_ID }}/data \
            -H "Authorization: Bearer ${{ secrets.DOCPIN_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d "{\"revenue\": $REVENUE, \"asOf\": \"$(date -u +%FT%TZ)\"}"

Keep the API key in your scheduler's secrets. It can publish and change every page in the workspace.

Update it from an AI app: MCP

With DocPin connected to Claude or ChatGPT (see MCP), two tools work with page data:

ToolArgumentsWhat it does
get_page_dataslug (and board if in one), or idReturns the page's current data and when it changed.
set_page_datathe page, data (object), optional replace: trueMerges data in (a null removes a key), or replaces everything with replace: true.

People can ask in plain language: "update the sales dashboard with these numbers", "clear the old regions from the dashboard data". An AI app should call get_page_data before replacing data, so it doesn't drop keys it didn't know about.

Scheduled AI tasks (for example a daily Claude task that pulls figures from a connected tool) can call set_page_data the same way.

Edit it by hand

In the DocPin web app, open the page and choose the Data tab. Edit the JSON and choose Save data. Only the keys you changed are sent, so a scheduled update made while you were editing isn't undone.

Limits

LimitValue
Size1 MB per page, measured as JSON text. Larger writes get 413.
ShapeThe top level must be a JSON object. Values can be any JSON.
Keys1 to 200 characters.
WritesAbout 30 a minute per workspace. Over that you get 429; wait a minute.
Checks from pagesdocpin.onData checks at most every 10 seconds per open page.

Who can see it

Page data is exactly as visible as the page. It's served from the page's own address:

When you change a page's password or people list, links that people opened before the change stop working for the page and its data until they open the page again.

Version previews never show the current data.

Never put secrets in page data: no API keys, passwords, tokens or personal information you wouldn't put on the page itself. If a page needs data from a private source, have your server or scheduled job fetch it and push only the results.

Errors

Errors come back as { "error": "Plain-English message" } with these statuses:

StatusMeaning
400The body isn't a JSON object, or a key is empty or too long.
401Missing or invalid API key, or the person who created the key left the workspace.
403DocPin took the page down.
404No such page in this workspace (check the id).
409The data changed several times while saving. Retry.
413Over 1 MB.
429Too many writes. Wait a minute.