How to Automate Spreadsheet Creation With One API Call
A step-by-step tutorial for creating spreadsheets programmatically. We will cover getting an API key, making your first request, adding formulas and formatting, and working in three languages: curl, Python, and JavaScript.
What you will build
By the end of this tutorial, you will be able to create a fully-formatted spreadsheet with data, formulas, number formatting, and a shareable link — all from a single API call. The spreadsheet will be accessible to anyone via URL, downloadable as XLSX or PDF, and editable in the browser.
We will use the OpenOfficeAI API, which is designed specifically for programmatic document creation. If you do not have an account yet, you can sign up for free — no credit card required.
Prerequisites
- An OpenOfficeAI account (free tier works for everything in this tutorial).
- Your API key, available from the dashboard after signing up.
- curl, Python 3, or Node.js installed on your machine (depending on which examples you want to follow).
1Get your API key
After signing up at openofficeai.com/signup, go to your dashboard. Your API key is displayed in the API Keys section. Copy it — you will need it for every request.
Your API key looks something like this: ooai_sk_a1b2c3d4e5f6.... Keep it secret. Do not commit it to version control. Use environment variables in production.
2Create your first spreadsheet
Let us start with the simplest possible request: a spreadsheet with a title and some data. Here it is in all three languages.
curl -X POST https://openofficeai.com/api/v1/sheets \
-H "Authorization: Bearer $OPENOFFICEAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "My First Spreadsheet",
"sheets": [{
"name": "Sheet1",
"data": [
["Name", "Department", "Salary"],
["Alice Chen", "Engineering", 125000],
["Bob Martinez", "Design", 110000],
["Carol Wu", "Marketing", 105000],
["David Kim", "Engineering", 130000]
]
}]
}'import requests
import os
response = requests.post(
"https://openofficeai.com/api/v1/sheets",
headers={
"Authorization": f"Bearer {os.environ['OPENOFFICEAI_API_KEY']}",
"Content-Type": "application/json",
},
json={
"title": "My First Spreadsheet",
"sheets": [{
"name": "Sheet1",
"data": [
["Name", "Department", "Salary"],
["Alice Chen", "Engineering", 125000],
["Bob Martinez", "Design", 110000],
["Carol Wu", "Marketing", 105000],
["David Kim", "Engineering", 130000],
]
}]
}
)
result = response.json()
print(f"Spreadsheet URL: {result['url']}")
print(f"Document ID: {result['id']}")const response = await fetch("https://openofficeai.com/api/v1/sheets", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENOFFICEAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "My First Spreadsheet",
sheets: [{
name: "Sheet1",
data: [
["Name", "Department", "Salary"],
["Alice Chen", "Engineering", 125000],
["Bob Martinez", "Design", 110000],
["Carol Wu", "Marketing", 105000],
["David Kim", "Engineering", 130000],
]
}]
})
});
const result = await response.json();
console.log("Spreadsheet URL:", result.url);
console.log("Document ID:", result.id);All three produce the same result. The API returns a JSON object with the document id, a shareable url, and the document metadata. The URL is immediately accessible — send it to anyone and they can view the spreadsheet in their browser.
3Add formulas
Spreadsheets without formulas are just data tables. OpenOfficeAI supports standard spreadsheet formulas using the same syntax you would use in Excel or Google Sheets. Any cell value that starts with = is treated as a formula.
response = requests.post(
"https://openofficeai.com/api/v1/sheets",
headers={"Authorization": f"Bearer {os.environ['OPENOFFICEAI_API_KEY']}"},
json={
"title": "Q1 Budget Tracker",
"sheets": [{
"name": "Budget",
"data": [
["Category", "Budget", "Actual", "Variance", "% Used"],
["Payroll", 50000, 48500, "=C2-B2", "=C2/B2"],
["Marketing", 15000, 17200, "=C3-B3", "=C3/B3"],
["Infrastructure", 8000, 7100, "=C4-B4", "=C4/B4"],
["Office", 5000, 4800, "=C5-B5", "=C5/B5"],
["Travel", 3000, 3900, "=C6-B6", "=C6/B6"],
["Total", "=SUM(B2:B6)", "=SUM(C2:C6)",
"=SUM(D2:D6)", "=C7/B7"]
]
}]
}
)Supported formula functions include SUM, AVERAGE, COUNT, MIN, MAX, IF, VLOOKUP, CONCATENATE, and most standard spreadsheet functions. Cell references work exactly as you would expect: B2 for a single cell, B2:B6 for a range, $B$2 for absolute references.
4Apply formatting
Formatting is specified in the formatting object on each sheet. Keys are cell ranges (like A1:E1) and values describe the formatting to apply.
const response = await fetch("https://openofficeai.com/api/v1/sheets", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENOFFICEAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Q1 Budget Tracker",
sheets: [{
name: "Budget",
data: [
["Category", "Budget", "Actual", "Variance", "% Used"],
["Payroll", 50000, 48500, "=C2-B2", "=C2/B2"],
["Marketing", 15000, 17200, "=C3-B3", "=C3/B3"],
["Infrastructure", 8000, 7100, "=C4-B4", "=C4/B4"],
["Office", 5000, 4800, "=C5-B5", "=C5/B5"],
["Travel", 3000, 3900, "=C6-B6", "=C6/B6"],
["Total", "=SUM(B2:B6)", "=SUM(C2:C6)",
"=SUM(D2:D6)", "=C7/B7"]
],
formatting: {
"A1:E1": {
bold: true,
background: "#18181b",
color: "#ffffff"
},
"B2:C7": { format: "$#,##0" },
"D2:D7": { format: "$#,##0" },
"E2:E7": { format: "0.0%" },
"A7:E7": {
bold: true,
borderTop: "2px solid #e4e4e7"
}
}
}]
})
});Available formatting options include:
- bold, italic, underline — boolean text styling.
- format — number format string (e.g.,
$#,##0.00,0.0%,yyyy-mm-dd). - background — cell background color (hex).
- color — text color (hex).
- fontSize — font size in points.
- align — horizontal alignment (left, center, right).
- borderTop, borderBottom, borderLeft, borderRight — CSS-style border strings.
5Work with multiple sheets
Real-world spreadsheets often have multiple sheets. The sheets array accepts multiple sheet objects. You can reference cells across sheets using the standard SheetName!A1 syntax in formulas.
curl -X POST https://openofficeai.com/api/v1/sheets \
-H "Authorization: Bearer $OPENOFFICEAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Sales Report — Multi-Region",
"sheets": [
{
"name": "North America",
"data": [
["Product", "Units", "Revenue"],
["Widget A", 1200, 36000],
["Widget B", 800, 32000],
["Total", "=SUM(B2:B3)", "=SUM(C2:C3)"]
]
},
{
"name": "Europe",
"data": [
["Product", "Units", "Revenue"],
["Widget A", 950, 28500],
["Widget B", 620, 24800],
["Total", "=SUM(B2:B3)", "=SUM(C2:C3)"]
]
},
{
"name": "Summary",
"data": [
["Region", "Total Revenue"],
["North America", "='"'"'North America'"'"'!C4"],
["Europe", "=Europe!C4"],
["Grand Total", "=SUM(B2:B3)"]
]
}
]
}'6Download and export
Every spreadsheet created through the API can be downloaded in multiple formats. Use the download endpoint with the document ID and your desired format.
curl -O -J https://openofficeai.com/api/v1/download/{document_id}?format=xlsx \
-H "Authorization: Bearer $OPENOFFICEAI_API_KEY"response = requests.get(
f"https://openofficeai.com/api/v1/download/{doc_id}",
headers={"Authorization": f"Bearer {os.environ['OPENOFFICEAI_API_KEY']}"},
params={"format": "pdf"}
)
with open("report.pdf", "wb") as f:
f.write(response.content)Supported export formats: xlsx, pdf, csv, and json. All formats are available on all plans, including the free tier.
7Integrate into your application
Once you have the basics working, integrating spreadsheet creation into a real application is straightforward. Here is a common pattern: a backend endpoint that accepts data from your frontend and creates a spreadsheet on demand.
import express from "express";
const app = express();
app.use(express.json());
app.post("/api/generate-report", async (req, res) => {
const { reportType, dateRange, data } = req.body;
// Transform your application data into spreadsheet format
const rows = [
["Date", "Customer", "Amount", "Status"],
...data.map(order => [
order.date,
order.customerName,
order.amount,
order.status,
])
];
// Add a totals row
rows.push([
"Total", "",
`=SUM(C2:C${data.length + 1})`,
""
]);
const response = await fetch(
"https://openofficeai.com/api/v1/sheets",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENOFFICEAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: `${reportType} Report — ${dateRange}`,
sheets: [{
name: "Report",
data: rows,
formatting: {
"A1:D1": { bold: true, background: "#f4f4f5" },
"C2:C100": { format: "$#,##0.00" },
}
}]
})
}
);
const result = await response.json();
// Return the shareable URL to your frontend
res.json({
spreadsheetUrl: result.url,
documentId: result.id,
});
});This pattern works with any backend framework. Your frontend makes a request to your server, your server calls the OpenOfficeAI API, and you return the shareable URL to the user. The user clicks the link and sees their spreadsheet instantly.
Common patterns and tips
Store your API key in environment variables
Never hardcode your API key. Use environment variables in every environment — local development, staging, and production. Most deployment platforms (Vercel, Railway, Heroku, AWS) have built-in environment variable management.
Handle errors gracefully
The API returns standard HTTP status codes. 201 means success. 400 means your request body has an error. 401 means your API key is invalid. 429 means you have hit the rate limit. Always check the status code before using the response.
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 201:
result = response.json()
print(f"Success: {result['url']}")
elif response.status_code == 429:
print("Rate limited. Wait and retry.")
else:
print(f"Error {response.status_code}: {response.json()['error']}")Use the free tier for development
The free tier gives you 500 API calls per month and 25 documents. That is more than enough for development and testing. You do not need to upgrade until you are ready to go to production. See our pricing page for details on all plans.
Batch data preparation, not API calls
Unlike some spreadsheet APIs that require multiple requests to build a document, OpenOfficeAI creates the entire spreadsheet in one call. This means you should do all your data preparation in your code before making the request. Query your database, transform the data, build the rows array, and then make a single POST request.
What to build next
Now that you know how to create spreadsheets via API, here are some ideas for what to build:
- Automated reporting. Connect to your database and generate weekly or monthly reports automatically using a cron job.
- User-facing exports. Add an "Export to Spreadsheet" button to your SaaS application that generates a formatted spreadsheet on demand.
- AI agent output. Give your AI agent the ability to produce real spreadsheets as part of its workflow.
- Invoice generation. Create a billing pipeline that produces professional invoices as downloadable PDFs.
- Data pipeline exports. End your ETL pipeline with a spreadsheet that stakeholders can immediately open and use.
Ready to start building? Create your free account and you will have your first spreadsheet created in under five minutes.
For the full API reference — including document creation, updating, deletion, sharing, and webhooks — see the API documentation.