UNSILOED_CHART. The function downloads a chart
image, asks Unsiloed for a chart-ready Markdown table, and converts the table to
numeric spreadsheet values. The finished formula looks like this:
A2. The value in B2 triggers another
status check when parsing takes longer than one formula execution. An optional
third argument returns a numeric x-axis for scatter charts. In the example
below, Unsiloed extracts 20 quarters from a dual-axis chart, including revenue
in millions of pounds and margin as a percentage. We then rebuild it as an
editable combination chart.

What We’ll Build
The custom function performs five operations:- It downloads a public chart image and uploads the bytes to
/parse. - It asks the page analyzer to end its response with one Markdown data table.
- It stores the returned job ID so later calculations can reuse it.
- It checks the job once during each calculation.
- It converts the table into validated, chart-ready rows and numeric series.
Show the Full Script
Show the Full Script
Code.gs, replacing its contents. The script reads the API key
from the script property configured in Step 3.Requirements for the Custom Function
Before you start, gather:- A Google account and a spreadsheet you can edit
- An Unsiloed API key from the Unsiloed dashboard
- A public PNG, JPEG, or TIFF URL that returns the image bytes
Step 1: Open the Apps Script Editor
The custom function lives in the Apps Script project attached to the spreadsheet. In Google Sheets, choose Extensions → Apps Script.
Code.gs in a new tab. Delete
the empty myFunction that Google adds to a new project.
Step 2: Build the Custom Function
We’ll build the same script in twelve focused sections. Keep each addition inCode.gs in the order shown below. If you copied the completed script from the
accordion, use this section to understand its request, cache, and
table-conversion logic.
2.1 Configure Chart Extraction
At the top ofCode.gs, add the API URL, cache limits, extraction prompt, and
API key helper:
UNSILOED_API_KEY in
Step 3.
2.2 Check the Parse Job
BelowunsiloedApiKey, add the function that Sheets calls:
@customfunction tag adds UNSILOED_CHART to Sheets autocomplete. Each
calculation performs one status request. If the job is still running, changing
refresh starts another calculation that checks the saved job ID.
2.3 Reuse or Create a Parse Job
BelowUNSILOED_CHART, add the helper that reads the cache before taking a lock,
then checks it again before submitting an image:
2.4 Validate and Clear Cached Jobs
BelowgetOrCreateChartJob, add helpers that reject malformed cache entries and
remove a failed or missing job without deleting a newer replacement:
2.5 Bound the Job Cache
BelowclearCachedChartJob, add cleanup and cache-key helpers:
2.6 Build the Chart Parse Request
BelowjobPropertyName, add the payload that tells Unsiloed how to analyze the
image and which response fields to return:
chart_data because the prompt already produces the
table. For charts embedded in multi-page documents, send extract_charts=true
instead and read the structured chart_data field on each chart segment. See
the parse job response reference
for that field.
2.7 Download the Source Image
BelowchartParsePayload, add the image downloader:
2.8 Send Authenticated API Requests
BelowfetchChartImage, add the shared request helper:
2.9 Select the Chart Data Table
BelowunsiloedRequest, add the helper that validates every extracted table:
TRUE as the optional third formula argument when a scatter chart needs a
numeric x-axis. In that mode, a missing or nonnumeric x value produces an error.
2.10 Parse Markdown Tables
BelowfirstChartRows, add the tolerant Markdown table parser:
2.11 Split Markdown Cells Safely
BelowisMarkdownRow, add the row parser and backslash helpers:
C:\temp keeps its literal backslash, while \| remains a pipe inside its
cell.
2.12 Validate Series and Numbers
At the bottom ofCode.gs, add the numeric-series and cell-value validators:
Code.gs contains all twelve sections, save the project and confirm that
Apps Script reports no syntax error. The finished script should use the
chart-v6 cache version and accept imageUrl, refresh, and numericX as
the function’s three arguments.

Step 3: Store Your API Key
Keep the API key out of spreadsheet cells and source code by storing it as a script property.Open the script properties
Add the API key
UNSILOED_API_KEY, paste your API key into its value
field, and click Save script properties.
Step 4: Extract the Chart Data
We’ll keep the image URL and refresh value separate from the formula so a status check doesn’t require editing the formula text.Add the image URL and refresh value

Run the custom function
A4 and enter:Loading... while the function submits or checks the parse
job. Keep the cells below and to the right of A4 empty so the result has
room to expand.Refresh an unfinished job
B2 from 1 to 2. Sheets
recalculates the function and checks the saved job instead of submitting
the image again. Repeat after another short wait if the job is still
processing.
Review the extracted table

revenue (£m) and margin (%) units in the headers while estimating the plotted
values from the chart’s pixels. For example, the extracted quarter 7 margin is
16.2, while the synthetic source data is approximately 16.15. Verify values
against source data before using them for consequential decisions.
The margin values use a 0–100 percentage scale, so 13.9 means 13.9%. Don’t
apply Sheets’ percentage format, which would display that value as 1,390%.
Each image URL reuses a saved job for up to 24 hours, subject to the 50-entry
cache limit. To deliberately submit a fresh job, change
UNSILOED_JOB_VERSION, save Code.gs, and change B2. If you instead delete
its UNSILOED_JOB_... script property, also change B2 to recalculate the
formula.
Step 5: Recreate the Chart in Google Sheets
The extracted cells become the data source for the native chart. Select the extracted category and value columns, including their headers. Then choose Insert → Chart.

Troubleshoot the Custom Function
'Pass a public HTTP image URL'
'Pass a public HTTP image URL'
'The URL did not return an image'
'The URL did not return an image'
'Add UNSILOED_API_KEY to the script properties'
'Add UNSILOED_API_KEY to the script properties'
The cell says 'Still processing'
The cell says 'Still processing'
The formula says 'Try the formula again'
The formula says 'Try the formula again'
The API returns an HTTP or credit error
The API returns an HTTP or credit error
The result could not expand
The result could not expand
Sheets rejects the formula separator
Sheets rejects the formula separator
=UNSILOED_CHART(A2; B2) instead.The extracted chart has missing or uncertain values
The extracted chart has missing or uncertain values

