Nesta página
Crie funções no Apps Script que buscam cotações da brapi dentro da planilha. Elas
funcionam com ativos que a função GOOGLEFINANCE não cobre, como os ETFs IMAB11,
WRLD11, IB5M11 e IRFM11.
Crie uma conta em brapi.dev e copie o token no painel.
/**
* Busca preços de múltiplos tickers em UMA requisição (recomendado).
* Uso: =BRAPI_BATCH(A2:A20; $A$1)
* @param {Range} tickers - Range com os códigos dos ativos (coluna)
* @param {string} token - Token da API brapi.dev
* @return {number[][]} Coluna com o preço de cada ativo
* @customfunction
*/
function BRAPI_BATCH(tickers, token) {
if (!tickers) return [["Erro: informe tickers"]];
if (token && typeof token === 'object' && token.length) {
token = token[0][0];
}
if (!token) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
token = sh.getRange('A1').getDisplayValue();
}
if (!token) return [["Erro: token brapi.dev ausente"]];
// Monta a lista de tickers a partir do range
var tickerList = [];
for (var i = 0; i < tickers.length; i++) {
var t = String(tickers[i][0] || '').toUpperCase().trim();
if (t) tickerList.push(t);
}
if (tickerList.length === 0) return [["Sem tickers"]];
// Uma única requisição para todos os tickers (separados por vírgula)
var url = 'https://brapi.dev/api/quote/' +
encodeURIComponent(tickerList.join(','));
var options = {
muteHttpExceptions: true,
headers: {
'Authorization': 'Bearer ' + token,
'User-Agent': 'GoogleSheets-brapi/1.0'
}
};
var response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() !== 200) {
return tickers.map(function() {
return ["HTTP " + response.getResponseCode()];
});
}
var json = JSON.parse(response.getContentText());
var results = (json && json.results) || [];
// Mapeia símbolo → preço para preservar a ordem do range
var priceMap = {};
for (var j = 0; j < results.length; j++) {
var sym = results[j].symbol;
var price = results[j].regularMarketPrice;
if (price == null) price = results[j].lastPrice;
if (price == null) price = results[j].close;
priceMap[sym] = price != null ? price : null;
}
// Retorna um array 2D na mesma ordem da coluna de entrada
return tickers.map(function(row) {
var key = String(row[0] || '').toUpperCase().trim();
if (!key) return [""];
var val = priceMap[key] != null ? priceMap[key] : priceMap[key + '.SA'];
return [val != null ? val : "Não encontrado"];
});
}
/**
* Busca o preço de UM ticker via brapi.dev (1 requisição por célula).
* Prefira BRAPI_BATCH para economizar requisições.
* Uso: =BRAPI_PRICE("PETR4"; $A$1)
* @param {string} ticker - Código do ativo (ex: "PETR4", "VALE3", "IMAB11")
* @param {string} token - Token da API brapi.dev
* @return {number} Preço atual do ativo
* @customfunction
*/
function BRAPI_PRICE(ticker, token) {
if (!ticker) return "Erro: informe ticker";
if (token && typeof token === 'object' && token.length) {
token = token[0][0];
}
if (!token) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
token = sh.getRange('A1').getDisplayValue();
}
if (!token) return "Erro: token brapi.dev ausente";
ticker = String(ticker).toUpperCase().trim();
var url = 'https://brapi.dev/api/quote/' + encodeURIComponent(ticker);
var options = {
muteHttpExceptions: true,
headers: {
'Authorization': 'Bearer ' + token,
'User-Agent': 'GoogleSheets-brapi/1.0'
}
};
var response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() !== 200) {
return "HTTP " + response.getResponseCode() + ": " +
response.getContentText().substring(0, 200);
}
var json = JSON.parse(response.getContentText());
var result = (json && json.results && json.results[0]) || null;
if (!result) return "Sem dados retornados";
var price = result.regularMarketPrice;
if (price == null) price = result.lastPrice;
if (price == null) price = result.close;
return price != null ? price : "Preço não encontrado";
}
/**
* Retorna dados completos de um ativo
* Uso: =BRAPI_DATA("PETR4"; $A$1; "symbol")
* @param {string} ticker - Código do ativo
* @param {string} token - Token da API
* @param {string} field - Campo desejado (regularMarketPrice, currency, shortName, etc)
* @return {any} Valor do campo solicitado
* @customfunction
*/
function BRAPI_DATA(ticker, token, field) {
if (!ticker) return "Erro: informe ticker";
if (!field) return "Erro: informe campo";
if (token && typeof token === 'object' && token.length) {
token = token[0][0];
}
if (!token) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
token = sh.getRange('A1').getDisplayValue();
}
if (!token) return "Erro: token ausente";
ticker = String(ticker).toUpperCase().trim();
var url = 'https://brapi.dev/api/quote/' + encodeURIComponent(ticker);
var options = {
muteHttpExceptions: true,
headers: {
'Authorization': 'Bearer ' + token,
'User-Agent': 'GoogleSheets-brapi/1.0'
}
};
var response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() !== 200) {
return "Erro HTTP " + response.getResponseCode();
}
var json = JSON.parse(response.getContentText());
var result = (json && json.results && json.results[0]) || null;
if (!result) return "Sem dados";
return result[field] || "Campo não encontrado";
}Cole o token na célula A1.
Liste os tickers na coluna A (a partir de A2) e use a fórmula em lote:
=BRAPI_BATCH(A2:A20; $A$1)A fórmula busca todos os tickers do intervalo em uma requisição.
Para buscar um único ativo, use:
=BRAPI_PRICE("PETR4"; $A$1)Com $A$1, a referência ao token não muda quando você arrasta a fórmula.
=BRAPI_PRICE("PETR4"; $A$1) # Petrobras PN
=BRAPI_PRICE("VALE3"; $A$1) # Vale ON
=BRAPI_PRICE("ITUB4"; $A$1) # Itaú Unibanco PN
=BRAPI_PRICE("BBDC4"; $A$1) # Bradesco PN=BRAPI_PRICE("IMAB11"; $A$1) # ETF IMA-B
=BRAPI_PRICE("IB5M11"; $A$1) # ETF IMA-B 5+
=BRAPI_PRICE("IRFM11"; $A$1) # ETF IRF-M
=BRAPI_PRICE("B5P211"; $A$1) # ETF NTN-B Principal=BRAPI_PRICE("WRLD11"; $A$1) # ETF Global
=BRAPI_PRICE("IVVB11"; $A$1) # ETF S&P 500
=BRAPI_PRICE("NASD11"; $A$1) # ETF Nasdaq=BRAPI_PRICE("^BVSP"; $A$1) # Índice Ibovespa=BRAPI_DATA("PETR4"; $A$1; "regularMarketPrice") # Preço
=BRAPI_DATA("PETR4"; $A$1; "currency") # Moeda
=BRAPI_DATA("PETR4"; $A$1; "shortName") # Nome curto
=BRAPI_DATA("PETR4"; $A$1; "regularMarketChange") # Variação do dia
=BRAPI_DATA("PETR4"; $A$1; "marketCap") # Valor de mercadoO Apps Script tem limites próprios, além dos limites da brapi:
| Recurso | Limite (contas gratuitas) |
|---|---|
UrlFetchApp.fetch por execução | 50 chamadas |
UrlFetchApp.fetch por dia | 20.000 chamadas |
| Tempo de execução por função | 30 segundos |
Com 30 ativos, BRAPI_PRICE faz 30 chamadas UrlFetchApp.fetch por atualização. BRAPI_BATCH faz 1.
| Comportamento | O que acontece |
|---|---|
HTTP 429 | Você passou do limite de requisições do plano. Espere ou mude de plano. |
HTTP 401 | Token inválido ou ausente. |
| Plano gratuito | 15.000 requisições/mês |
BRAPI_BATCH. Uma requisição com vários tickers conta como uma.| Cenário | Requisições/mês |
|---|---|
30 ativos com BRAPI_BATCH, 3x/dia | ~90 (30 dias × 3 × 1 req) |
30 ativos com BRAPI_PRICE, 3x/dia | ~2.700 (30 dias × 3 × 30 req) |
50 ativos com BRAPI_BATCH, 3x/dia | ~270 (30 dias × 3 × 3 blocos) |
Confira se o token está na célula A1 ou no segundo parâmetro da fórmula.
O token é inválido. Copie o token completo do painel.
Você passou do limite de requisições. Use BRAPI_BATCH ou mude de plano.
O ticker é inválido ou o ativo não existe. Confira o código.
A função passou de 30 segundos. Use menos tickers por chamada.