If you already run part of your packaging workflow in Google Sheets — quoting, planning, comparing box sizes — you can pull real dieline measurements straight into a spreadsheet. In this post we build a small Google Sheets tool that takes a template catalog name, loads the values that template needs, lets you edit them, and returns the bounding box of every part. No servers to run, no deploy — everything lives inside the sheet.
We use the Dieline Dimensions API, which is built for exactly this: send a template id plus a few dimensions, get back the flat size of each part. It is the lightweight sibling of the full Dielines API — no files to download, just numbers.
The finished sheet works in two clicks from a custom menu:
becf-11a02) into a cell and choose Load required variables. The tool fills in a small table of the fields that template needs, pre-filled with sensible defaults.To keep things simple, we only load the required variables. Every template has a handful of optional toggles too, but the required ones (usually length, width, height) are all you need to get a meaningful measurement, and they keep the sheet uncluttered.
dim_.
Every request sends two headers: your key as Authorization: Bearer dim_... and Dimensions-Api-Version: 1.0. The base URL is https://api.diecuttemplates.com. We store the key inside the sheet's script (not in a cell), so it never shows up in the spreadsheet itself.
The whole tool is built on just two requests.
curl -i -X GET \
"https://api.diecuttemplates.com/dimensions/becf-11a02?unit=mm" \
-H "Authorization: Bearer dim_your_key_here" \
-H "Dimensions-Api-Version: 1.0"
The response describes the template. The part we care about is variables — each one tells you its name, its data_type, whether it is required, and a default_value:
{
"dieline_template": {
"type": "dieline_template",
"id": "becf-11a02",
"variables": [
{ "name": "length", "data_type": "length", "required": true, "default_value": { "value": 200, "unit": "mm" } },
{ "name": "width", "data_type": "length", "required": true, "default_value": { "value": 100, "unit": "mm" } },
{ "name": "height", "data_type": "length", "required": true, "default_value": { "value": 40, "unit": "mm" } },
{ "name": "overflow", "data_type": "boolean", "required": false, "default_value": { "value": false } }
]
}
}
Our tool keeps only the entries where required is true and drops the rest — that is the "for simplicity" choice we made above.
Once you have edited the values, send them back and ask for the parts. Add "area": true to also get the material area of each part.
curl -i -X POST \
"https://api.diecuttemplates.com/dimensions/becf-11a02/parts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer dim_your_key_here" \
-H "Dimensions-Api-Version: 1.0" \
-d '{
"variables": { "unit": "mm", "length": 200, "width": 100, "height": 40 },
"area": true
}'
You get one part per piece of the box, each with a bounding_box (the flat width and height) and, because we asked, an area:
{
"part_list": {
"type": "part_list",
"dieline_template_id": "becf-11a02",
"total": 1,
"parts": [
{
"type": "part",
"name": "default",
"category": "carton",
"bounding_box": { "unit": "mm", "width": 280.0, "height": 180.0 },
"area": { "value": 48847.29, "unit": "mm2" }
}
]
}
}
Create a new Google Sheet and lay out two labelled cells at the top so the tool knows what to read:
becf-11a02.mm or in.Everything else — the variables table and the results — the script writes for you, starting a few rows down.
Google Sheets can talk to an API through Apps Script, a bit of JavaScript that runs on Google's servers (so there is nothing to install and no browser security to fight). Open Extensions → Apps Script, delete the placeholder, paste the code below, and press Save. Reload the spreadsheet and a new Dimensions API menu appears.
const API_HOST = 'https://api.diecuttemplates.com';
const API_VERSION = '1.0';
const CATALOG_CELL = 'B1'; // you type the catalog name here
const UNIT_CELL = 'B2'; // 'mm' or 'in'
const HEADER_ROW = 5; // the variables table starts just below this row
const RESULTS_COLUMN = 7; // results are written from column G onward
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Dimensions API')
.addItem('1. Load required variables', 'loadVariables')
.addItem('2. Get bounding boxes', 'getBoundingBoxes')
.addSeparator()
.addItem('Set API key', 'setApiKey')
.addToUi();
}
function setApiKey() {
const ui = SpreadsheetApp.getUi();
const response = ui.prompt('Paste your Dimensions API key (starts with dim_)', ui.ButtonSet.OK_CANCEL);
if (response.getSelectedButton() !== ui.Button.OK) {
return;
}
PropertiesService.getScriptProperties().setProperty('DIMENSIONS_API_KEY', response.getResponseText().trim());
ui.alert('API key saved.');
}
function baseHeaders() {
const key = PropertiesService.getScriptProperties().getProperty('DIMENSIONS_API_KEY');
if (!key) {
throw new Error('No API key set. Use the "Dimensions API -> Set API key" menu first.');
}
return { 'Authorization': 'Bearer ' + key, 'Dimensions-Api-Version': API_VERSION };
}
// Step 1: read the catalog name, fetch the template, and write ONLY the
// required variables (name, type, and an editable default value).
function loadVariables() {
const sheet = SpreadsheetApp.getActiveSheet();
const catalog = String(sheet.getRange(CATALOG_CELL).getValue()).trim();
const unit = String(sheet.getRange(UNIT_CELL).getValue()).trim() || 'mm';
if (!catalog) {
SpreadsheetApp.getUi().alert('Type a catalog name in cell ' + CATALOG_CELL + ' first.');
return;
}
const url = API_HOST + '/dimensions/' + encodeURIComponent(catalog) + '?unit=' + encodeURIComponent(unit);
const response = UrlFetchApp.fetch(url, { method: 'get', headers: baseHeaders(), muteHttpExceptions: true });
if (response.getResponseCode() !== 200) {
SpreadsheetApp.getUi().alert('Error ' + response.getResponseCode() + ': ' + response.getContentText());
return;
}
const variables = JSON.parse(response.getContentText()).dieline_template.variables;
const requiredVariables = variables.filter(function (variable) {
return variable.required === true;
});
// Clear any previous run, then write a small Variable / Type / Required / Value table.
sheet.getRange(HEADER_ROW, 1, sheet.getMaxRows() - HEADER_ROW + 1, sheet.getMaxColumns()).clearContent();
sheet.getRange(HEADER_ROW, 1, 1, 4).setValues([['Variable', 'Type', 'Required', 'Value']]).setFontWeight('bold');
const rows = requiredVariables.map(function (variable) {
const defaultValue = variable.default_value ? variable.default_value.value : '';
return [variable.name, variable.data_type, 'yes', defaultValue];
});
if (rows.length > 0) {
sheet.getRange(HEADER_ROW + 1, 1, rows.length, 4).setValues(rows);
}
}
// Step 2: read your edited values, ask the API for the parts, and write the
// bounding box (and material area) of each one next to the inputs.
function getBoundingBoxes() {
const sheet = SpreadsheetApp.getActiveSheet();
const catalog = String(sheet.getRange(CATALOG_CELL).getValue()).trim();
const unit = String(sheet.getRange(UNIT_CELL).getValue()).trim() || 'mm';
const variableRowCount = sheet.getLastRow() - HEADER_ROW;
if (variableRowCount < 1) {
SpreadsheetApp.getUi().alert('Load the variables first (menu step 1).');
return;
}
const table = sheet.getRange(HEADER_ROW + 1, 1, variableRowCount, 4).getValues();
const variables = { unit: unit };
table.forEach(function (row) {
const name = String(row[0]).trim();
const value = row[3];
if (name === '' || value === '') {
return;
}
variables[name] = value;
});
const url = API_HOST + '/dimensions/' + encodeURIComponent(catalog) + '/parts';
const response = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
headers: baseHeaders(),
payload: JSON.stringify({ variables: variables, area: true }),
muteHttpExceptions: true
});
if (response.getResponseCode() !== 200) {
SpreadsheetApp.getUi().alert('Error ' + response.getResponseCode() + ': ' + response.getContentText());
return;
}
const parts = JSON.parse(response.getContentText()).part_list.parts;
sheet.getRange(HEADER_ROW, RESULTS_COLUMN, sheet.getMaxRows() - HEADER_ROW + 1, 5).clearContent();
sheet.getRange(HEADER_ROW, RESULTS_COLUMN, 1, 5)
.setValues([['Part', 'Category', 'Width (' + unit + ')', 'Height (' + unit + ')', 'Area']]).setFontWeight('bold');
const resultRows = parts.map(function (part) {
return [part.name, part.category, part.bounding_box.width, part.bounding_box.height, part.area ? part.area.value : ''];
});
if (resultRows.length > 0) {
sheet.getRange(HEADER_ROW + 1, RESULTS_COLUMN, resultRows.length, 5).setValues(resultRows);
}
}
dim_... key. You only do this once; Apps Script remembers it.becf-11a02) and mm into B2.Change a value and run step 2 again — the numbers update. That is the whole loop: it turns your spreadsheet into a live size calculator for any template in the catalog.
material (the board thickness, in your chosen unit) as a required variable, so it appears in the table automatically — like the one pictured above. If a template needs it but does not list it, add a material row by hand with a value like 0.5.unit in B2 is sent with every request and labels the result columns, so millimetres and inches never get mixed up.This same two-call pattern works from anything that can make an HTTP request — a Python script, a Zapier step, your own back end. Once you can fetch a template's variables and post them back for measurements, you can wire packaging sizes into whatever tool you already use.
Full reference docs live at the Dieline Dimensions API documentation, and you can manage keys and credits from the Dieline Dimensions API page. If you build something with it, we would love to see it.