curl --request POST \
--url https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history \
--header 'Content-Type: application/json' \
--header 'apikey: <api-key>' \
--data '
{
"p_ticker": "<string>",
"p_from": "2023-12-25",
"p_to": "2023-12-25",
"p_after": null
}
'import requests
url = "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history"
payload = {
"p_ticker": "<string>",
"p_from": "2023-12-25",
"p_to": "2023-12-25",
"p_after": None
}
headers = {
"apikey": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {apikey: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({p_ticker: '<string>', p_from: '2023-12-25', p_to: '2023-12-25', p_after: null})
};
fetch('https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'p_ticker' => '<string>',
'p_from' => '2023-12-25',
'p_to' => '2023-12-25',
'p_after' => null
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"apikey: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history"
payload := strings.NewReader("{\n \"p_ticker\": \"<string>\",\n \"p_from\": \"2023-12-25\",\n \"p_to\": \"2023-12-25\",\n \"p_after\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("apikey", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history")
.header("apikey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"p_ticker\": \"<string>\",\n \"p_from\": \"2023-12-25\",\n \"p_to\": \"2023-12-25\",\n \"p_after\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["apikey"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"p_ticker\": \"<string>\",\n \"p_from\": \"2023-12-25\",\n \"p_to\": \"2023-12-25\",\n \"p_after\": null\n}"
response = http.request(request)
puts response.read_body[
{
"ticker": "<string>",
"trade_date": "2023-12-25",
"isin": "<string>",
"segment": "<string>",
"min_price": 123,
"max_price": 123,
"avg_price": 123,
"last_price": 123,
"ref_price": 123,
"oscillation_pct": 123,
"trade_count": 123,
"quantity": 123,
"notional_brl": 123,
"file_status": "<string>",
"source": "<string>"
}
]{
"code": "22023",
"message": "<string>",
"details": "<string>",
"hint": "<string>"
}{
"code": "22023",
"message": "<string>",
"details": "<string>",
"hint": "<string>"
}{
"code": "22023",
"message": "<string>",
"details": "<string>",
"hint": "<string>"
}trade_consolidated_history
Daily prints of one ticker of B3’s consolidated trade file (TradeInformationConsolidatedFile), segment FORWARD only, as published, oldest first: the 46 Brazilian fixed-income ETFs COTAHIST does not carry (IMAB11, B5P211, IRFM11, LFTS11, …) and 21 other FORWARD tickers. A ticker not held raises 22023 (this function holds only the FORWARD segment; a COTAHIST ticker is in quote_history), never an empty set. The close is last_price. ref_price is B3’s reference price, NOT a trade and NEVER a close: a session with no trade carries only ref_price, and last_price (with min_price, max_price, avg_price, trade_count, quantity and notional_brl) is NULL there. There is NO opening price: the file has none and none is filled from another source. notional_brl is this file’s volume and is not comparable with COTAHIST’s or B3’s BDI (BOVA11 on 2026-09-29: R587,459,700.14here,R588,765,462.41 in COTAHIST). Prices are NOT adjusted for distributions: a return from last_price is a price-only return, which understates the real return of an ETF that distributes income (many fixed-income ETFs pay coupons); for one that reinvests the difference is small. Retention: the source’s oldest session was 2025-06-10 when checked on 2026-09-30, so history starts there. Row cap: more than 1000 rows RAISES 22023 (never trimmed) unless p_after pages: ” = first page, then the last row’s trade_date as ‘YYYY-MM-DD’; a page shorter than 1000 is the last. Or narrow p_from/p_to. Depth is in api.coverage().
Row cap. A window producing more than 1000 rows raises SQLSTATE 22023 naming this function. Nothing is trimmed to fit — PostgREST would silently cut the response at 1000 and a cut-short series is indistinguishable from one that simply ends. This function pages: send p_after = "" for the first page, then the key copied from the last row; a page shorter than 1000 is the last. p_after = null is whole-result mode, which is what refuses.
curl --request POST \
--url https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history \
--header 'Content-Type: application/json' \
--header 'apikey: <api-key>' \
--data '
{
"p_ticker": "<string>",
"p_from": "2023-12-25",
"p_to": "2023-12-25",
"p_after": null
}
'import requests
url = "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history"
payload = {
"p_ticker": "<string>",
"p_from": "2023-12-25",
"p_to": "2023-12-25",
"p_after": None
}
headers = {
"apikey": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {apikey: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({p_ticker: '<string>', p_from: '2023-12-25', p_to: '2023-12-25', p_after: null})
};
fetch('https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'p_ticker' => '<string>',
'p_from' => '2023-12-25',
'p_to' => '2023-12-25',
'p_after' => null
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"apikey: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history"
payload := strings.NewReader("{\n \"p_ticker\": \"<string>\",\n \"p_from\": \"2023-12-25\",\n \"p_to\": \"2023-12-25\",\n \"p_after\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("apikey", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history")
.header("apikey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"p_ticker\": \"<string>\",\n \"p_from\": \"2023-12-25\",\n \"p_to\": \"2023-12-25\",\n \"p_after\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1/rpc/trade_consolidated_history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["apikey"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"p_ticker\": \"<string>\",\n \"p_from\": \"2023-12-25\",\n \"p_to\": \"2023-12-25\",\n \"p_after\": null\n}"
response = http.request(request)
puts response.read_body[
{
"ticker": "<string>",
"trade_date": "2023-12-25",
"isin": "<string>",
"segment": "<string>",
"min_price": 123,
"max_price": 123,
"avg_price": 123,
"last_price": 123,
"ref_price": 123,
"oscillation_pct": 123,
"trade_count": 123,
"quantity": 123,
"notional_brl": 123,
"file_status": "<string>",
"source": "<string>"
}
]{
"code": "22023",
"message": "<string>",
"details": "<string>",
"hint": "<string>"
}{
"code": "22023",
"message": "<string>",
"details": "<string>",
"hint": "<string>"
}{
"code": "22023",
"message": "<string>",
"details": "<string>",
"hint": "<string>"
}Authorizations
The publishable key (sb_publishable_…), on every request. It is NOT a JWT — sending it as Authorization: Bearer is rejected as an invalid JWT. It identifies the project, not you, and maps to the Postgres anon role.
Body
Response
The result set, oldest first. An unknown id is an empty array, not a 404 and never a guessed value.
Was this page helpful?