API Reference
Base URL: https://datalake.mt2data.cloud
All data endpoints require authentication. See Authentication for how to obtain an access token.
POST /oauth/token
Obtain an OAuth 2.0 access token using client credentials.
Request:
POST /oauth/token HTTP/1.1
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "your-client-id",
"client_secret": "your-client-secret"
}
Also accepts application/x-www-form-urlencoded.
Response (200):
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
Response (401):
{
"error": "invalid_client",
"error_description": "Invalid client credentials"
}
GET /catalog
Get metadata for all files you are authorized to access. Returns Symbol identifiers, human-readable descriptions, and R2 file paths.
The Description field is read from the index CSV's ShortDescriptionPt column (the short Portuguese label), falling back to ShortDescription where that cell is empty.
Response (200):
{
"clientId": "your-account",
"files": [
{
"Symbol": "IbgeGdpAgroInd",
"Description": "PIB - Agropecuária Ind",
"FileName": "BaseDeDadosMacro/ContasNacionais/IBGE/IbgeGdpAgroInd.csv"
}
],
"count": 1
}
Performance: ~1s — use this as your primary way to discover available files.
GET /list
List files that appear in your catalog and physically exist in R2, with size and upload timestamp. Uses batched HEAD verification.
Parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
limit | No | 1000 | Max files to return |
Response (200):
{
"files": [
{
"symbol": "IbgeGdpAgroInd",
"description": "PIB - Agropecuária Ind",
"size": 1048576,
"uploaded": "2026-01-15T10:30:00Z"
}
],
"count": 1,
"limit": 1000,
"truncated": false
}
Performance: ~2s for a full catalog (~500 files).
GET /count
Returns the total number of accessible files that physically exist in R2.
Response (200):
{ "count": 506 }
Performance: ~2s.
GET /info/
Get metadata for a specific file by its Symbol identifier without downloading it.
GET /info/YOUR_SYMBOL HTTP/1.1
Authorization: Bearer <access_token>
Response (200):
{
"symbol": "YOUR_SYMBOL",
"size": 1048576,
"uploaded": "2026-01-15T10:30:00Z",
"etag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"httpMetadata": {},
"customMetadata": {}
}
etag is also returned as an ETag header, alongside Last-Modified. Keep it
and send it back as If-None-Match on the download — see below.
Performance: ~0.5s.
GET /download/
Download a file by its Symbol identifier. Returns binary content.
GET /download/YOUR_SYMBOL HTTP/1.1
Authorization: Bearer <access_token>
Response (200): File content as binary stream. Content-Type and
Content-Disposition are forwarded from R2, alongside ETag, Last-Modified,
Content-Length and Accept-Ranges: bytes.
Don't re-download what hasn't changed
Send the ETag you last received as If-None-Match. An unchanged file answers
304 Not Modified with no body, which matters for the larger objects — a 20 MB
file costs one small round trip instead of 20 MB.
curl -H "Authorization: Bearer $TOKEN" \
-H 'If-None-Match: "d41d8cd98f00b204e9800998ecf8427e"' \
-o file.parquet -w '%{http_code}\n' \
"https://datalake.mt2data.cloud/download/YOUR_SYMBOL"
HEAD works the same way if you only want the headers.
Resuming a large download
Range is supported, and a ranged request answers 206 Partial Content with a
Content-Range header:
curl -H "Authorization: Bearer $TOKEN" -H 'Range: bytes=0-1048575' \
"https://datalake.mt2data.cloud/download/YOUR_SYMBOL" -o first-mb.bin
Response (304): Empty, when If-None-Match matches the current file.
Response (403):
{
"error": "Access denied",
"message": "Symbol not found in your subscription"
}
Response (404):
{
"error": "Not found",
"message": "File does not exist"
}
Performance: ~0.5s + file transfer time.
GET /
Direct file download by file path (alternative to Symbol-based access).
curl -H "Authorization: Bearer $TOKEN" \
"https://datalake.mt2data.cloud/path/to/your-file.parquet" -o your-file.parquet
Error Codes
| HTTP | Meaning |
|---|---|
| 400 | Bad request (OAuth: invalid_request, unsupported_grant_type) |
| 401 | Missing or expired credentials (OAuth: invalid_client) |
| 403 | Access denied — file not in client's index, or invalid API key |
| 404 | File not found in R2, or catalog not found |
| 412 | A precondition other than If-None-Match failed |
| 429 | Too many downloads. Cache what you fetch and revalidate with If-None-Match; Retry-After says how long to wait |
| 500 | Internal server error |