The data guide

Your data.
On your screen.

Start with one connection and one widget. We’ll help you get a real value on screen, then make it your own.

No connection required if you’d rather type your own text or numbers.

A quick orientation

Connect once.
Make it yours.

  1. Add a source

    A source is the Sheet or endpoint WidgetWire reads. Paste its link once. One source can power as many widgets as you like.

  2. Choose what to show

    In a widget, tap a field—like Value or Caption—then pick a source, a sheet and a cell. Or just type a value. Lists and charts use rows.

  3. Save and install

    Preview your design in the app, save it, then add the widget through iOS. Nothing is saved until you tap Save.

01 / Google Sheets

From sheet to screen.

You’ll need a Google Sheet that can be read without signing in. WidgetWire reads it; it never edits your spreadsheet.

  1. Set up your rows.

    Put a short name at the top of each column in row 1 and one item per row underneath. Avoid merged cells. Download our CSV and import it into a new Sheet using File → Import in Google Sheets on a computer.

    Download example spreadsheet CSV ↓

    On a phone, you can enter the small table below in the Sheets app instead. The full CSV adds Date, Status, Text and Active columns for the other recipes.

  2. Choose link access.

    In Google Sheets, open Share → General access, choose Anyone with the link and set the role to Viewer. Copy the link and save the sharing change. On iPhone, look for Manage access if General access isn’t shown.

    Download/export access must also be allowed. Work or school accounts may restrict sharing. Google’s sharing help · Import help

  3. Connect in WidgetWire.

    Open Sources, tap + (or Connect if empty), choose Google Sheets, paste the link and tap Connect. No Google sign-in or API key is needed. You don’t pick a tab here: the whole spreadsheet is connected, and you choose a sheet each time you pick a cell.

  4. Check what came through.

    Open the saved source. For a one-tab spreadsheet, look under Columns and Data: Name, Value and Percent should appear, with Design and 20 in row 2. A spreadsheet with several tabs shows how many sheets it has instead; you’ll see their cells when you fill a field. Then make your first widget.

Enter these cells starting at A1
NameValuePercent
Design200
Build4050
Review60100
Launch 🚀80100
Which Sheet link should I use? What about tabs?

Use the normal docs.google.com/spreadsheets/d/…/edit link, not a “Publish to web” /d/e/…/pubhtml link. Any tab’s link works; you don’t need a separate source for each tab.

When you fill a field, WidgetWire asks Which sheet? if the spreadsheet has more than one tab, then shows that tab’s cells. So one widget can use cells from several tabs of the same spreadsheet. Tabs are remembered by their ID, so renaming a tab doesn’t break anything. Formulas are read as their exported values, not run inside WidgetWire.

02 / JSON endpoints

A URL for your data.

An endpoint is a web address that returns data directly—not a dashboard, a login page or an API documentation page. WidgetWire sends an HTTPS GET request to that address.

  1. Get a working endpoint.

    Use your service’s data URL, or host the example JSON below on an HTTPS server. Opening the URL should return JSON. Downloading a file to your phone alone does not create an endpoint.

  2. Add it to Sources.

    Tap + → JSON / REST API, paste the Endpoint URL, set Authentication and any HTTP headers your provider needs, then tap Connect. Public endpoints need no credentials.

  3. Check the rows, then design.

    Open the saved source and inspect Columns and Data. WidgetWire turns the JSON into a grid: row 1 holds the field names, sorted A to Z, and each object is a row below. With the example below you’ll see Name in column A, Percent in B and Value in C, with 20 in C2. You pick cells from this grid just like a Sheet. Continue to your first widget.

A minimal data response
[
  {"Name":"Design","Value":20,"Percent":0},
  {"Name":"Build","Value":40,"Percent":50},
  {"Name":"Review","Value":60,"Percent":100},
  {"Name":"Launch 🚀","Value":80,"Percent":100}
]

Download the complete example JSON ↓

The complete file includes the extra fields needed for every layout recipe. Return a successful HTTP response, ideally with Content-Type: application/json.

Just exploring? Try a public demo endpoint.

No server or key needed. This JSONPlaceholder example is fictional data from a third-party service, not a WidgetWire backend.

Public demo URL
https://jsonplaceholder.typicode.com/todos/1

Add this URL as JSON / REST API with no authentication. Expect one row with completed, id, title and userId. Create a Stat widget, tap Value, choose the demo source and tap the cell under id (B2): it should show 1.

The demo is read-only sample content and may be unavailable. Replace it with your own endpoint when you’re ready.

Connect an endpoint that needs a key.

Use the method your API provider specifies. Credentials go into Key, not into a widget’s text or template.

Bearer token
Enter just the token in Key. WidgetWire adds Authorization: Bearer ….
Custom header
Enter the header name, such as X-API-Key, in Header and the secret in Key.
Query parameter
Enter the parameter name, such as api_key, in Parameter and the secret in Key.

Keys are stored in the iOS Keychain; the library stores a reference. Prefer header authentication when available: query keys become part of the request URL and may appear in server logs. Use read-only, narrowly scoped credentials.

OAuth sign-in, POST bodies and automatic token renewal are not supported. Never include keys in a template, screenshot or support message.

Other JSON shapes and field names

The most predictable format is an array of flat objects. Each object is a row; its properties become columns. A single flat object, a one-level wrapper such as {"data":[{"Name":"Design","Value":20}]}, and parallel arrays also work.

Parallel arrays need at least two columns of equal length with more than one item. One nested object of parallel arrays is accepted. If several arrays of objects exist, the first non-empty one by alphabetically sorted key is used.

Deeply nested collections, pagination and JSONPath selection are not supported. Flatten fields or return a small summary from your server. Numbers stay numeric, booleans become true/false, and null or missing cells become empty text.

New JSON sources order columns alphabetically. Refreshes keep the existing column order and add new fields on the right, so a picked cell like C2 keeps pointing at the same field. Keep field names and capitalization stable.

Optional / Request settings

More than one header? No problem.

Some APIs need a workspace ID, a version header or an extra key alongside Authentication. In the JSON connection form, scroll to HTTP headers → Add header. Add one name and value per row. The keyboard’s Next moves from name to value; Done dismisses it. You can configure up to 16 headers.

Example headers—use the names and values your provider requires.

X-Workspace-ID
Example value: workspace-example
Select your workspace.
X-API-Version
Example value: 2026-09
Request a specific API version.
Accept
Example value: application/json
Response format (already the default).

Bearer Authentication works alongside these headers. Don’t add a second Authorization row when Bearer is selected, or duplicate the named header used by Authentication. Header names are case-insensitive. iOS manages transport headers such as Host and Content-Length; WidgetWire explains if a name conflicts.

Edit or remove headers later.

Open Sources → your JSON connection → HTTP headers. Leave a saved value blank to keep it, type a replacement to change it, or use the minus button to remove the row. Tap Save, then Refresh source to check the response. Every widget using that source uses the updated headers.

03 / Your first connected widget

Let’s see that 20.

Use the four-row spreadsheet or JSON example above. The smaller public demo is different: pick the cell under id there to see 1.

  1. Start with Stat.

    Open Widgets, tap + and choose Stat. It opens in the editor at Medium size; tap Small under the preview if you’d like it smaller.

  2. Tap the Value field.

    In the editor’s Data tab, under What to show, tap Value. Choose your saved source under Where does it come from? You don’t need to paste its link again.

  3. Pick the sheet, then the cell.

    If your spreadsheet has more than one tab, choose the sheet first. Then tap the cell holding 20 in the grid and tap Use. In the example Sheet, that’s B2. In the example JSON, it’s the cell under Value in row 2.

  4. Check the result.

    The preview should show 20. Want a whole column instead? Tap Value again and tap the column letter at the top of the grid. For Value, Stat then shows the column’s average: 50, from 20, 40, 60 and 80.

  5. Save, then add it to your screen.

    Tap Review & Save, then Save Widget. Nothing is saved before this, and Cancel asks before throwing changes away. On your Home Screen, touch and hold an empty area, choose Edit → Add Widget, find WidgetWire and choose the matching size. When iOS asks which Widget to show, choose your saved design. To switch designs later, touch and hold the widget and choose Edit Widget.

See Apple’s installation guide for system-specific help. When you edit a saved widget later, tap Save to update your screen.

One cell

Tap a field, then pick a source, a sheet and a cell. The field shows exactly that cell, like a total in B2. For a single field you can also tap a column letter to use every row.

Rows from a range

Lists and charts have Rows. Choose Add rows from a sheet and select cells or whole columns, like A2:B. Each sheet row becomes a widget row.

Typed value

Tap a field, choose Type a value and tap Use. Dates get a calendar and numbers a number keyboard. It won’t change with the source.

A widget reads one source. If you pick a cell from a different source, WidgetWire asks first, then clears the fields that used the old one. Typed values stay.

04 / Pick your next idea

A recipe for every layout.

These recipes use the example spreadsheet: Name in column A, Value in B, Percent in C, Date in D, Status in E and Text in F, with data in rows 2 to 5. Read “Value → B2” as “tap the Value field, then cell B2.” Open just the layouts you need.

Stat One important number

Value → B2. Shows 20. Tap the column letter B instead and Stat shows the column’s average, 50. Caption is optional: type it or pick a cell.

List Rows at a glance

Add rows from a sheet → tap column letters A and B (A2:B). Design 20, Build 40, Review 60, Launch 🚀 80, in sheet order. With only column A you get labels without values. Small widgets stack each label and value; wider widgets place them side by side.

Progress, Ring & Gauge A goal taking shape

Percent → C3. Shows 50%. Use 0–100; values outside that range stop at 0 or 100. Or leave Percent as a plain number and set a Goal: Percent → B3 (40) with Goal typed as 80 also shows 50%. Caption is optional.

Split Two numbers together

Left number → B2; Left label → A2; Right number → B5; Right label → A5. Shows 20 Design beside 80 Launch 🚀. Labels are optional; type your own if you prefer.

Sparkline & Columns Change over time

Each row has an optional X-axis field and a Value. For many points at once, choose Add points from a sheet → tap column letter B for the numbers, tap Use, then tap column letter A for the x-axis labels (or Skip). You get 20, 40, 60, 80 labelled Design to Launch 🚀, with the latest value, 80, called out.

The numbers and labels are picked separately, so they can be anywhere: columns apart, a row across the top, or another tab. Tap a row number to use a whole row; it keeps taking new columns as you add them. Points pair up in order. Tap the points row later to change the numbers or labels, or to remove the labels. Selecting two side-by-side columns at once (A2:B) also works: the first becomes the labels.

Full dates on the x-axis are shortened, so 2026-09-01 reads “Sep 1”. When labels get crowded, some are skipped, but the latest one always shows. Turn the axis off with Style → Show x-axis labels. Rows stay in sheet order; dates are not sorted for you. Columns shows the latest 8 values at Small size and 16 at larger sizes.

Bars Compare a few things

Add rows from a sheet → A2:B. One bar per row, in sheet order, labelled with the Name. Bars extend from zero: negative values to the left, positive values to the right. Unreadable values keep their row with a dash.

Leaderboard Highest first

Add rows from a sheet → A2:B. Names with scores, sorted highest first: Launch 🚀 80, Review 60, Build 40, Design 20.

Heatmap A pattern of activity

Add rows from a sheet → column B (B2:B). A tile for each number in sheet order; stronger shading means a higher value. The headline is the average, 50. When space is limited, the latest tiles are shown. It isn’t a calendar.

Grid A compact summary

Add rows from a sheet → column B (B2:B). Count 4, average 50, highest 80, lowest 20.

Status Count each category

Add rows from a sheet → column E (E2:E). Ready 2, Queued 1, Done 1, most common first. Blank cells are skipped.

Next Up & Countdown Something to look forward to

Next Up: Title → A3; Date → D3. Shows Build, its date (January 9, 2027) and how many days away it is.
Countdown: Date → D3; Event → A3. Counts the days until Build.

To let the widget find the soonest date for you, tap the column letters instead: Date → column D and Title or Event → column A. It then uses the nearest date today or later. Or type a date with the calendar. Replace the example’s January 2027 dates once they’ve passed.

Big Text Words worth keeping

Text → F2; Byline → A2. “Make room for what matters.” with the byline Design. Pick another row’s cells for another message, or type your own.

Dots Little wins, counted

Add rows from a sheet → column C (C2:C). 2 of 4 complete. A value of 100 or higher fills a dot; true/false does not count. Blank or unreadable cells are skipped; use 0 for an unfinished item so it stays in the count.

Custom Your own JSON layout

Custom has plain fields, no Rows section. For our full template, tap each field and then a column letter: Value → B; Percent → C; Row label → A; Row value → B. The template combines the number (the average, 50), the meter and the repeated rows. Continue to custom layouts.

Keep the data predictable.

Ready-made background templates start with editable personal content; no connection or layout JSON is required. Basic layout previews show examples until you add your values. Required fields must be filled before saving; captions and bylines marked Optional can stay empty.

Cells stay put
A picked cell is read by its address, like B2. If you insert, delete or sort rows or columns, that address may now hold something else. Tap the field and pick it again.
Ranges side by side
A range’s columns fill a row’s fields in order, so put them next to each other: label first, then value. JSON fields are sorted A to Z, so in the example JSON Name and Value aren’t neighbours. Use Add row and pick each cell, or reorder your data.
Percentages
Use 0–100, not 0–1. Values like 50% work too. Percentage-formatted Google Sheets cells export the displayed percentage.
Numbers
Use plain numbers for charts. Avoid mixed units, text and a totals row inside a range.
Dates
Prefer YYYY-MM-DD. Dates use the device calendar and time zone; past dates are ignored by upcoming-event layouts.
Column names
They matter when you tap a column letter for a single field: that choice follows the name in row 1, which is case-sensitive. Renaming the header breaks it.

05 / More control, when you want it

Data JSON ≠ template JSON.

Data JSON supplies the values. Add its URL in Sources. Template JSON describes the design. In Widgets, tap + and choose Custom, then Edit JSON template. Keep the two separate.

  1. Start with a small template.

    Paste the example below in the template editor and tap Done. It displays your Value and Caption fields.

  2. Fill the fields separately.

    Back in the Data tab, tap Value, pick your saved source and cell B2 to show 20. Or tap the column letter B for the average, 50. Optionally type a Caption or pick a cell for it.

  3. Preview and save.

    Choose a size that suits your layout, inspect the preview, then Save Widget. The in-app Reference lists the supported building blocks.

A complete starter template
{
  "padding": 18,
  "root": {
    "type": "vstack",
    "align": "leading",
    "spacing": 8,
    "children": [
      {"type":"text","text":"{{value}}","size":36},
      {"type":"text","text":"{{caption}}","size":14}
    ]
  }
}

Download all-components template JSON ↓

The larger example is designed for Large or Full Screen. It includes all 11 building blocks: vstack, hstack, zstack, text, spacer, divider, bar, ring, symbol, rect and rows.

Use live placeholders in a template.

{{value}}, {{caption}} and {{percent}} use the matching fields. {{col.Name}} reads the first row’s Name field. Inside a rows block, use {{row.label}}, {{row.value}} and {{row.index}}.

Placeholders are not executable code. Unknown names stay visible to help you spot typos.

Load a design from a URL.

In the template editor, open Examples → Load from URL…. Supply an HTTPS URL that returns template JSON directly. Keeping it linked lets the app re-fetch the design; unlink it to edit a local copy.

Template URLs do not use the data source’s credentials. Use a public, non-sensitive template with no secrets. A template endpoint must return a valid design, not data rows or an HTML repository page.

06 / Know what to expect

Fresh, at iOS’s pace.

After changing your Sheet or endpoint, open Sources → your connection and tap the circular-arrow button (Refresh source). Check Last sync and, for a one-tab source, the Data preview first. Then check your widget. A refresh also re-reads every other tab your widgets pick cells from.

In a connected widget’s Data tab, Refresh → Every sets how often you’d like new data: 15 minutes, 1 hour, 6 hours or 1 day. iOS manages refresh timing, so treat this as a wish, not a schedule.

Add a refresh button to the widget itself.

Open a connected Home Screen design, then turn on Data → Refresh → Refresh button on widget and tap Save. It’s off by default, so existing designs keep their clean header. Custom layouts get a separate header so the control doesn’t cover their content.

Tap the installed widget’s arrow to fetch its source and any linked layout without opening the app. A small spinner shows while it works; afterwards, the time of the last update appears beside the arrow (or the date, if it wasn’t today). On failure, the last good content stays visible and the arrow becomes a warning button you can tap to retry. In-app previews show the control but do not send requests when tapped.

This control is offered for Home Screen designs with a connected source or linked custom template, not personal-only designs. iOS still manages execution and redraw timing; the button does not enable continuous polling, guarantee instant updates or override API rate limits.

200 data rows
WidgetWire stores the first 200 and reports the full response row count. Calculations use only the stored rows. For a total across thousands of records, return a small pre-aggregated summary.
Short request budgets
App connections have a 20-second timeout per request; installed-widget refreshes use up to 15 seconds per request. A Sheet may need extra metadata requests. Keep responses small and respect your provider’s rate limits.
Fewer rows on screen
List, Bars and Leaderboard show up to 3 in Small, 4 in Medium, 8 in Large and 12 in Full Screen. They can calculate from more rows than fit on screen.
The same data, different sizes
Connections work across supported Home Screen and Lock Screen layouts. Full Screen authoring uses them too; native placement requires iOS 27 and a compatible WidgetWire build.

07 / Find the step that needs attention

Back on track.

First check the source in Sources. If the data is wrong there, fix the connection. If it’s right there but wrong in the editor, tap each field and check which cell or rows it uses. If the editor is right but the Home Screen is stale, make sure you tapped Save, check the selected saved design and allow iOS time to refresh.

Google asks me to sign in.

Check the Sheet link in a signed-out browser. Review General access, Viewer download/export access and any organization restrictions. WidgetWire cannot sign in to a private Sheet. Don’t make sensitive data public to work around this; use a safe, separate dataset.

The wrong cell, tab or rows appear.

Look at the field in the Data tab, or tap the row. On a spreadsheet with several tabs it shows the sheet name and address, like “Weight · B7”. Pick again if it’s the wrong sheet or cell. Cells are read by address, so inserting, deleting or sorting rows can move your data away from it. A range picked by tapping cells stops at its last row unless Include rows added later is on.

I get 401, 403 or an HTML response.

401 usually means missing or invalid credentials; 403 means access was refused. Check Authentication, the header/parameter name and key permissions. HTML usually means a web page or sign-in redirect. Your endpoint must return JSON directly. See authentication setup.

I see an average instead of my total.

That field uses a whole column: you tapped a column letter, and Stat averages its numbers. Tap the field again and pick the one cell that holds your total, or return a one-row summary from your endpoint. In the example, column B gives 50; cell B2 gives 20.

Values are blank, or a meter looks wrong.

A message like “B2” is missing means that cell is now empty or gone; tap the field and pick it again. Check number formats too. Percentages use 0–100; 0.5 means half of one percent, not 50%. Dots need numbers, not true/false. If you used a whole column, check its header’s spelling and capitalization.

There is no upcoming event.

Next Up and Countdown ignore past dates. With one cell, only that date counts; tap the Date column letter instead to use the soonest date in every row. Use unambiguous dates such as YYYY-MM-DD and include an event today or later. Update the sample’s January 2027 dates when needed.

The service times out or returns 429.

Check the connection and provider status; reduce the response size. For HTTP 429, wait before trying again. WidgetWire does not follow pagination or continuously poll. Repeated manual refreshes may make a rate limit worse.

Back to the guide ↑