Use case

Persistent storage for AI agent structured output

AI agents that extract or generate structured data need somewhere to put it. Instadash gives the agent a hosted grid at a stable URL — push JSON or JSONL once, then read it back via API, MCP, or markdown without re-running the agent or re-streaming tokens.

The shape of the problem

You're running an agent that extracts data — scraping a job board, classifying tickets, parsing financial reports. The output is structured: rows and columns. But the agent emits it as a JSON blob in a tool response, or worse, a markdown table in the chat. As soon as the run ends, the data is gone unless you pipe it somewhere.

Common workarounds:

  • Re-run the agent on demand. Burns tokens, gives non-deterministic outputs.
  • Persist to a database. Requires schema, ops, drivers, and a separate read path the agent can use.
  • Save to a Google Sheet. OK for humans, awkward for agents and crawlers.

What Instadash does

Push the structured output once. The push streams JSONL to /ingest, lands the rows in R2 storage, and registers a grid record. From that point the data is accessible four ways:

# 1. HTML page (humans + crawlers)
open https://instadash.io/<handle>/<slug>
 
# 2. JSON API (downstream code)
curl https://instadash.io/<handle>/<slug>/rows
 
# 3. Markdown table (LLM context windows)
curl https://instadash.io/<handle>/<slug>/llms.md
 
# 4. MCP tool call (other agents)
# Any MCP client connected to https://mcp.instadash.io/mcp
# can call instadash_read({ handle, slug })

The agent doesn't need to know about any of these targets — it just pushes. Consumers pick the read surface that fits.

A complete example

Agent code that extracts a list and pushes it:

// Inside your agent / tool implementation
const rows = await extractStructuredData(input) // returns Array<Record>
 
await fetch('https://instadash.io/ingest', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.INSTADASH_API_KEY}`,
    'Content-Type': 'application/json',
    'X-Grid-Slug': 'q3-extracted-leads',
    'X-Grid-Visibility': 'private',
  },
  body: JSON.stringify(rows),
})

Five minutes later, another agent reads it back:

const r = await fetch('https://instadash.io/<handle>/q3-extracted-leads/rows', {
  headers: { Authorization: `Bearer ${process.env.INSTADASH_API_KEY}` },
})
const { rows } = await r.json()

Or an LLM context window pulls the markdown:

const markdownTable = await fetch(
  'https://instadash.io/<handle>/q3-extracted-leads/llms.md',
).then(r => r.text())

No model call, no token spend, no hallucination — the data is the source of truth.

When this is the right tool

Reach for an Instadash grid when:

  • Multiple consumers (agents, humans, jobs) need the same structured output.
  • You want the output addressable by URL so it can be cited and embedded.
  • You need a version history without writing migrations.
  • The data is wider than one row but narrower than a full database — dozens to a few million rows, columns that fit on a screen.

When it's NOT the right tool: write-heavy transactional systems with row-level locking, unstructured text corpora (use a vector store), or media (use R2 / S3 direct).

FAQ

Why not just have the agent return a JSON object each time?

A returned JSON object is ephemeral. Every downstream consumer (another agent, a human, a job) re-prompts the model to get the same data, which costs tokens, can drift between calls, and gives no audit trail. Pushing once to Instadash makes the output addressable, cacheable, and citable.

How is this different from writing to a database?

A database needs a schema, a connection, and ops. Instadash infers schema from the rows you push, exposes the result over HTTPS plus MCP, and gives every grid a versioned URL. No DDL, no migrations, no driver.

Can the agent update an existing grid instead of creating a new one?

Yes. Pushing to an existing handle/slug creates a new version. Old versions stay readable, and the JSON API serves the latest by default. See the time machine doc for version pinning.

How big can a grid be?

A single grid is designed to hold up to millions of rows. Beyond that, sharding by handle/slug is the canonical pattern — e.g. one grid per month of agent runs.

Related

More use cases

Related across sections

canonical: /use-cases/ai-agent-structured-output