Concept
APIs in one minute
An API is a web address that returns data for programs instead of a web page for people. Most APIs return JSON:
{ "base": "USD", "rates": { "INR": 83.2, "EUR": 0.92 } }
In JavaScript, JSON.parse(text) turns that text into an object you can use: data.rates.INR.
A GET request
We'll use a free test API that needs no key:
function getTodo() {
const res = UrlFetchApp.fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = JSON.parse(res.getContentText());
console.log(data.title, data.completed);
}
Handling errors properly
By default fetch throws an error for any 4xx/5xx response. Use muteHttpExceptions to check the status yourself:
function safeGet(url) {
const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const code = res.getResponseCode();
if (code !== 200) {
console.error(`HTTP ${code}: ${res.getContentText().slice(0, 200)}`);
return null;
}
return JSON.parse(res.getContentText());
}
| Code | Meaning |
|---|---|
| 200 | OK |
| 400 | Bad request (your data is wrong) |
| 401 / 403 | Not authorised (key missing or wrong) |
| 404 | Not found (wrong URL) |
| 429 | Too many requests — slow down |
| 500+ | Server problem — try again later |
Sending data: POST
function createPost() {
const payload = { title: 'New order', body: 'Ring x2', userId: 1 };
const res = UrlFetchApp.fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
console.log(res.getResponseCode(), res.getContentText());
}
API keys and headers
Most real APIs need a key, usually sent in a header:
const key = PropertiesService.getScriptProperties().getProperty('API_KEY');
const res = UrlFetchApp.fetch('https://api.example.com/v1/rates', {
headers: { Authorization: 'Bearer ' + key },
muteHttpExceptions: true
});
Never paste keys directly into code that others can see — keep them in Script Properties (lesson 3 of this module).
Example: load a list into a sheet
function loadUsers() {
const users = safeGet('https://jsonplaceholder.typicode.com/users');
if (!users) return;
const out = [['ID', 'Name', 'Email', 'City']];
users.forEach(u => out.push([u.id, u.name, u.email, u.address.city]));
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Users');
sheet.clearContents();
sheet.getRange(1, 1, out.length, out[0].length).setValues(out);
sheet.getRange('F1').setValue('Updated: ' + new Date().toLocaleString('en-IN'));
}
Add an hourly time-driven trigger and the sheet refreshes itself.
Fetching many URLs at once
UrlFetchApp.fetchAll([...requests]) sends several requests in parallel — much faster than a loop of single calls.
const ids = [1, 2, 3];
const responses = UrlFetchApp.fetchAll(ids.map(id => ({
url: `https://jsonplaceholder.typicode.com/todos/${id}`,
muteHttpExceptions: true
})));
const titles = responses.map(r => JSON.parse(r.getContentText()).title);
Key points
UrlFetchApp.fetch(url, options)for GET/POST;JSON.parsethe result.- Always use
muteHttpExceptions: trueand checkgetResponseCode(). - Keep API keys in Script Properties; send them as headers.
fetchAllfor many URLs; cache results that don't change often.