Skip to main content
Every completed run returns an edit_url alongside the download_url. Drop it in an <iframe> and your end-users see the generated document rendered as a full spreadsheet / document / presentation surface inside your app — they can scroll, zoom, switch sheets or slides, and inspect everything the agent produced.
It’s called edit_url because the surface behind it is the Overten editor — the same editor the Overten web app uses for its authenticated users. End-users can browse and edit the document live; changes (cell values, text, slide content) persist back to the run’s artifact, so the next download_url fetch serves the edited version. For programmatic / agent-driven edits, call the relevant generate endpoint again with the same run_id and a new prompt — it composes with manual edits.

download_url vs edit_url — when to use which

Most integrations use both: edit_url inside their dashboard so users see results immediately, download_url on a “Download” button so users can take the file elsewhere.

How it works end-to-end

  1. You call POST /excel/generate (or word/slides), get back edit_url.
  2. You embed that URL in an iframe in your UI.
  3. Overten validates the token, loads the run’s file from storage, and streams a rendering of the document into the iframe.
  4. Every subsequent user action (scroll, click, zoom) stays between the browser and Overten — your app never sees the content, never handles bytes, never runs a viewer itself.
The token is what ties “this iframe open right now” to “this specific run”. It expires and is scoped — see below.

Token semantics

  • Opaque — a random string, not a JWT. Generated by Overten, validated by Overten. Don’t try to parse it client-side.
  • Scoped to one run + your org — if someone copy-pastes the URL into another app, the token still only unlocks this document for your org.
  • Short-lived, sliding — 15 minutes from the last user activity. Active viewer sessions refresh the TTL automatically; idle sessions (user closed the tab) expire on their own.
  • No explicit revoke endpoint today. The short sliding TTL is the mitigation. If you suspect a leak before a token has expired naturally, contact support with the run_id and we can invalidate on our side.

Basic embed

React:

How edits land

Two paths — they compose:
  1. Direct in-iframe edits. The user types, changes a cell, rewrites a paragraph, moves a slide. Edits auto-save to the run’s artifact (same storage location download_url points at). The next fetch serves the updated bytes.
  2. Agent-driven edits via API. Call the relevant generate endpoint with the original run_id and a new prompt; the agent picks up whatever state is current (including the user’s in-iframe edits) and applies the change:
Agent follow-ups via run_id are cheap because the agent resumes from state — it’s not rebuilding the workbook, just applying the delta. Every generate response includes fresh edit_url and download_url.

Getting a fresh URL after expiry

If the original edit_url has expired (e.g. the user opens your dashboard the next morning and tries to reopen a doc from yesterday), call the generate endpoint again with the original run_id and a no-op prompt:
The response includes a fresh edit_url with a new token. Resume via run_id is cheap because the agent already has state.

What edit_url is NOT

  • Not a shareable public link. Tokens are scoped to one viewer session. Don’t email an edit_url — it’ll work for 15 minutes, then stop, and before then it unlocks your org’s run to whoever clicked.
  • Not a download. The iframe renders the document live; bytes never land on the user’s disk via this route. For downloads, use download_url.
  • Not a programmatic write API. In-iframe edits work for human users, but your server-side code should use the generate endpoint with run_id to apply structured changes — that’s auditable, has a ledger row, and doesn’t require a browser.
  • Not a hosted Office install. Your end-user doesn’t need Excel / Word / PowerPoint locally. The viewer runs entirely in the browser.

Security notes

  • Mint per viewer. Don’t store one edit_url server-side and serve it to multiple users. The token is meant for one session — each user should get a freshly-minted URL.
  • Strip tokens from logs / analytics. Drop the token query param before recording page URLs in your observability tools.
  • Restrict frame ancestors. If you serve edit_url in an <iframe>, set a Content-Security-Policy on your parent page that limits which origins can frame your dashboard, so an attacker can’t frame your app and read the iframe’s state via JS.
  • Prefer your own domain for the parent page. The token is only meaningful in-browser; someone who captures the URL during a session and opens it from another host still has to get past the sliding TTL.

White-label / custom branding

By default, the viewer shows standard Overten chrome (header, logo). Enterprise customers can get a white-label version with custom branding — contact support. If you don’t want to use the Overten viewer at all:
  • Use download_url and render the file with your own tooling (Google Drive viewer, OnlyOffice, SheetJS, native Office apps).
  • Or fetch the file bytes server-side and hand them to your preferred renderer.
The API returns both download_url and edit_url on every run, so you can switch between approaches per-user or per-route without changing your generation code.