Skip to main content

Retro Funding API Documentation

The following are examples of how to query the OSO API to get information about Retro Funding projects and metrics.

Projects

Get all projects in the round

query projectsInRound {
oso_projectsByCollectionV1(
where: {
collectionNamespace: { _eq: "retro-funding" }
}
limit: 5
) {
projectId
projectName
collectionId
collectionName
}
}

Get a project by Atlas ID

query GetAtlasProject($atlasId: String!) {
oso_projectsV1(limit: 1, where: { projectName: { _eq: $atlasId } }) {
projectId
projectName
description
displayName
projectNamespace
projectSource
}
}

Variables:

{
"atlasId": "0x08df6e20a3cfabbaf8f34d4f4d048fe7da40447c24be0f3ad513db6f13c755dd"
}

Get DefiLlama slugs for a project

query GetAtlasArtifacts($atlasId: String!) {
oso_artifactsByProjectV1(where: {
projectName: { _eq: $atlasId },
artifactSource: { _eq: "DEFILLAMA" }
}) {
artifactId
artifactName
artifactSource
}
}

Variables:

{
"atlasId": "0x08df6e20a3cfabbaf8f34d4f4d048fe7da40447c24be0f3ad513db6f13c755dd"
}

Get GitHub repositories for a project

query GetGitHubRepos($projectId: String!) {
oso_artifactsByProjectV1(where: {
projectId: { _eq: $projectId },
artifactSource: { _eq: "GITHUB" }
}) {
artifactId
artifactName
artifactNamespace
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ="
}

Metrics

See all metric IDs

query GetMetricIds {
oso_metricsV0 {
metricId
metricName
}
}

Get timeseries metrics for a project over a date range

query GetTimeseriesMetrics(
$projectId: String!,
$metricIds: [String!]!,
$startDate: Oso_Date!,
$endDate: Oso_Date!
) {
oso_timeseriesMetricsByProjectV0(
where: {
projectId: { _eq: $projectId },
sampleDate: { _gte: $startDate, _lte: $endDate },
metricId: { _in: $metricIds }
}
) {
metricId
sampleDate
amount
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"metricIds": [
"+CYPj5teekBILVKfpi7dWcV4Qjzn5QDjc4fxl61+Q/Q=", # transactions
"1PD0AamFG56j+rMmIyuOjGZhYyH+CLe2mmgzWLIPgvg=", # gas fees
"qlmqaIagTHAic/MX57vOmSprhncNDLYghKF0dM9+m3w=", # tvl
"PE/HlkQj+5mUPwKeOt3SDiJUA0aL6Ywp3mbvtckk5zM=" # active addresses
],
"startDate": "2025-01-01",
"endDate": "2025-02-28"
}

Get metrics for a specific date

query GetTimeseriesMetricsByDate(
$metricId: String!,
$projectId: String!,
$date: Oso_Date!
) {
oso_timeseriesMetricsByProjectV0(
where: {
metricId: { _eq: $metricId },
projectId: { _eq: $projectId },
sampleDate: { _eq: $date }
}
) {
metricId
sampleDate
amount
}
}

Variables:

{
"metricId": "PE/HlkQj+5mUPwKeOt3SDiJUA0aL6Ywp3mbvtckk5zM=",
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"date": "2025-02-28"
}

Get transaction metrics

query GetTransactionMetrics(
$projectId: String!,
$startDate: Oso_Date!,
$endDate: Oso_Date!
) {
oso_timeseriesMetricsByProjectV0(
where: {
projectId: { _eq: $projectId },
sampleDate: { _gte: $startDate, _lte: $endDate },
metricId: { _in: [
"+CYPj5teekBILVKfpi7dWcV4Qjzn5QDjc4fxl61+Q/Q=", # OPTIMISM
"I9PgkRs4ZvvhJoA4A3ttP4OHW5xuJkEq0SrPzVIqN64=", # BASE
"aXBn856tlU8mg2Z3047UmP7kpVMOC1gpazXl55srHrI=" # INK
] }
}
) {
metricId
sampleDate
amount
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"startDate": "2025-02-01",
"endDate": "2025-02-28"
}

Get active addresses metrics

query GetActiveAddressesMetrics(
$projectId: String!,
$startDate: Oso_Date!,
$endDate: Oso_Date!
) {
oso_timeseriesMetricsByProjectV0(
where: {
projectId: { _eq: $projectId },
sampleDate: { _gte: $startDate, _lte: $endDate },
metricId: { _in: [
"PE/HlkQj+5mUPwKeOt3SDiJUA0aL6Ywp3mbvtckk5zM=", # OPTIMISM
"G2aj792VVSZhk/oENCPGdapeVEozGum9W0o+Y0A5D9w=", # BASE
"YVlXddV9S4PooUOtWsYX5+w9HjhJ55FWCqqIL8i6oH4=" # INK
] }
}
) {
metricId
sampleDate
amount
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"startDate": "2025-02-01",
"endDate": "2025-02-28"
}

Get gas fees metrics

query GetGasFeesMetrics(
$projectId: String!,
$startDate: Oso_Date!,
$endDate: Oso_Date!
) {
oso_timeseriesMetricsByProjectV0(
where: {
projectId: { _eq: $projectId },
sampleDate: { _gte: $startDate, _lte: $endDate },
metricId: { _in: [
"1PD0AamFG56j+rMmIyuOjGZhYyH+CLe2mmgzWLIPgvg=", # OPTIMISM
"dBiekfqo+sEtNxDbBkQGorouPypHsgDGZr4SLlonQIg=", # BASE
"Zmd1uqzZJu/s1aEBfKoNIsI1zr1HW4L4TvmFGWz1dww=" # INK
] }
}
) {
metricId
sampleDate
amount
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"startDate": "2025-02-01",
"endDate": "2025-02-28"
}

Get TVL metrics

query GetTVLMetrics(
$projectId: String!,
$startDate: Oso_Date!,
$endDate: Oso_Date!
) {
oso_timeseriesMetricsByProjectV0(
where: {
projectId: { _eq: $projectId },
sampleDate: { _gte: $startDate, _lte: $endDate },
metricId: { _in: [
"qlmqaIagTHAic/MX57vOmSprhncNDLYghKF0dM9+m3w=", # OPTIMISM
"ss5IHd8zzw7KGYM1PWGYFe7H2fVLq8x8CJZwVBI8nLc=", # BASE
"PTkbAgVzNKiRx2stgyLeWaq5KGxrhwwBmfOCN5YmP1o=" # INK
] }
}
) {
metricId
sampleDate
amount
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"startDate": "2025-02-01",
"endDate": "2025-02-28"
}

Dependencies (Coming Soon!)

Get dependent projects

query GetDependentProjects($projectId: String!) {
oso_dependenciesV0(where: { toProjectId: { _eq: $projectId } }) {
toProjectId
fromProjectId
dependencyType
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ="
}

Reference

Metric IDs for Onchain Builders

ChainActive Addresses (Daily)Gas Fees (Daily)Transactions (Daily)DefiLlama TVL (Daily)Contract Invocations (Daily)
AUTOMATAQdEMc/9T7A9uHmGyebYqTgZtK8RMA4lUDE5vBZP8yYQ=pzNqT8Daqw9cVBYtLmUabuHeMOKoqKKIhTWxXkYrpzM=UyoNy8OtyDs7zMAvbWrTkHkQivER8/ch/4sGuXzIBy8=-q4NLzrfmhVgSYYqjehgcKlF7UieUf2voBEujC+NUFTA=
BASEG2aj792VVSZhk/oENCPGdapeVEozGum9W0o+Y0A5D9w=dBiekfqo+sEtNxDbBkQGorouPypHsgDGZr4SLlonQIg=I9PgkRs4ZvvhJoA4A3ttP4OHW5xuJkEq0SrPzVIqN64=ss5IHd8zzw7KGYM1PWGYFe7H2fVLq8x8CJZwVBI8nLc=8vTagJLAu5fbgEOQ6nqnLsRqbQ7dDOQANWfiaPKDVPc=
BOBooVpyQAjLTc+L/pUepYBtDtiRvd6CqA35bEdRbfMuXU=UsJkCKoOnWHj21QXFJR8ZI44SAcpW4y4slfY7tO+hEs=YQEnSzTkB1cX2Pp7zNCR2M8o15dXmkdKK59OmtaWvH4=Myz6ifp4t62tT3uXov0qe5eOSYX4pasxjUzOzDyxvwk=7TxBAoGkHbFQVdlDuEc3DaBnnhv1OndNhDU3CPuoQgk=
CYBERbmtrI5K28X/rHxageGh+VPttf7GHZEbAUItmr8dhWe8=dorNwoQhkRkspfHJUT1Ko3KdKBvc66bLri8p+Vs9LOs=BfhS2uIH7oaR7OOuckigqPeU8h543PLnifzHwJppSlc=-6AvLGOSx2UUp3dpKpo1LDvSOIDBSEhvS9Q0v6RnRhjc=
FRAXxdxWbfeAuQawUUnx7SM+WWycBoMrfQtNcSAa6OcKtRI=Gq9oWmIzQlRK9oBCKFl9Hq6pJ1+cLJ0YehoDqMgFiDc=6Iy0wZ9CmmlN7SyCXkdKe30wDb8s4QphG5gvre4hxG8=5+SjFSEgi1CurNH1pVdGEXLbXuTTSXj6w17ma8w/qlE=0X0E2Qw4Yw7O6LT7F/0T2Suvw653kaOBbZDLN3Pyrzc=
HAM9oCVh0sV1tiFxMRFHPNJpgNmsRIm5NUKmhHd1cHpmSc=UI4Ta1SgepKrMldOUWlHoQjKRoAVZsy5CcagqCLs7zQ=po1+unS65d5x++FeMSm+7ziGuGcFLuiNkX+gbimdnBY=-47RtkDIh7ngSFkzF7NOQyNPaklRSEh3qk646NVBWR9E=
INKYVlXddV9S4PooUOtWsYX5+w9HjhJ55FWCqqIL8i6oH4=Zmd1uqzZJu/s1aEBfKoNIsI1zr1HW4L4TvmFGWz1dww=aXBn856tlU8mg2Z3047UmP7kpVMOC1gpazXl55srHrI=PTkbAgVzNKiRx2stgyLeWaq5KGxrhwwBmfOCN5YmP1o=WOxUb39soikSlTz0N9gJZh9UkU5v8+TLRAFanTBWHhE=
KROMAR/AoozORX2lQvbwY8XXNIrsgbyYIKqvLPLiE8pd3kes=BDkCiphCMikILGoRru32ca7nZv3SMwQiWCaglqdjygU=GCj6MTzi3j6AWC2X9+e6NX6YfzVp40UxEa0hHUQIY4c=J7lEviP96Q3/7G3d/f401LAI6kGfjT6wzG+ZODStke8=7KViuoILkoOnzVVzje2b/x+5NreQPCIKyPg2wfNRWkU=
LISKr/PI23PyEA/ke7QvGlLZKqh5xFsv3LA8yVzIo2cGhc8=WRqIZSiYhqshpdLzine30aLZzrgBMk2VE54LjX5XtYw=PsNrB6WSZE572GEHsN4P7AnyfNJzEWTTfv++kxI3Yp4=dpw811b5/55RV9CZfnpkGSdLlOP1hdp0OF952XVUTWU=ZzjWGe/z2Pp2O/YVFdE9pqehiyguEA9aU151JmYhL0o=
LYRAN5rcFZ7X5puoKkvcWJIEpunzsEKY9j9A0wNFAK8ckfU=AMw6OBo4fFmxlSKHRHRPQfoKGPEmqn4rPVqDUurMHiE=uHuZJnyQ8YM88ki2BfYKUW05SW9vPkZz8L3a9s9QeWQ=-4GCrq1tV4lG2wog4x5QDTZlagC596ePXb81VTJ70iPI=
METAL3PmYaM6TSzeSUaegJELWPREj341+9E5NDH/ycVVwE+g=WpFQBuYoeR60ZkEdq7cLfj2fIk7tjk/P58/Y9/9UcKA=tuzBBz5ZoPatqMPi+FGRQlc+e1a86M7sI+FNnh/r04w=-Equrcnwc9BB4hiIfBnUERlYfkS/YAIOySc4TxaUO6ik=
MINTdojiObKfwKwo9H51BLnlSeW4qSlUhjBTkhp9TR1A5vo=7hOXfiIhXdOxobTRvSXOROojLY/V8vg0INh5RJ3N0a8=aXD0aVKcN2wv4Iueac3g59noHfx4zFyYMfrtKru/jZg=ki01wlulG50z6M9l8l5sQehPU9rDrxFmutPQqDUhIiM=VbulzPqVTPfCYb25Mjb9bQdJLzc1ikWPeGlux0fOQG8=
MODEj7FEQ7G/ysZGCQDVMolgGA575NBed9nnv7Sos1EBLSc=UYS/nGacZGua8TkIidJnB6jEXMNoJym9o79LrILlHKM=F5Jov1gVA9cms2q3rm51MsVeo+i1Mhbqg2k2xmWeGXE=ndFsC8I6H09EX6VAYQ59iKF4oaCTOkylu08tqVI+6gY=9pij1uGT9MQExHMn80lNumID1qJYgK13KHFd831EkCg=
OPTIMISMPE/HlkQj+5mUPwKeOt3SDiJUA0aL6Ywp3mbvtckk5zM=1PD0AamFG56j+rMmIyuOjGZhYyH+CLe2mmgzWLIPgvg=+CYPj5teekBILVKfpi7dWcV4Qjzn5QDjc4fxl61+Q/Q=qlmqaIagTHAic/MX57vOmSprhncNDLYghKF0dM9+m3w=OVljq6aZt9O5d5Bk0RpoAEXJ+nJr80fkry5+f7RUuRk=
ORDERLYkrGm5ldFpz2rucJU3/bpQ/YUp1+Wzg/Tzc2l5/Phl04=9sIaU9P33t5IXsKtGRZdvELh9Eo9rjK94C+1q2PgniM=ZTMr6/nJUDNlDacMk5TuzdyQZsrPBmpYE4Gmen1K6Mo=-tkBVLeBe0w2hwkx06ZXmOX1SBo4LbkpkJrrotdLyNqE=
POLYNOMIALTZXfsntBS+NNEe/XYLwnbV+rzNSc2wIIbDIuN+EQTbw=59ZUc7ZNdPqkd9y5CNhprWxcpZcCKancDfQ0KcmvzeI=SxfVVXXf6F8WGIi7uoB1HtNcaR/sHqbxI3MXxYYXtms=UiLK0j/dZtUWZUiLLB1CzdjkN2xGi/PMVWNvhUS03MU=bVI151haJ2r61X0fAxSaId6GcSkbjzCtvenssir2xyQ=
RACEWqW/XS5Rf1h55Y8e+Aqn1CD51UBSDmk0EbiKPcI7Jz0=Zy5WZtLLI+w8TBAUFy5CDO+Uf5ijhkY4sTLul0OixLI=ISQ6eIIKp0B9iAk/nx0eQMWZ2ehB2RvEJHenZLJLgzQ=-I9of/x8ND34LG7QhxMz3qQ5D8pGu5lp1mDgTSpKOyx4=
REDSTONEcuuJZDt6Np+B3eweuTZjluazY7JlxJws/lTWckv/i8E=CSirey5zj7PgDS76fCKmRF55kR6ZZ/myIj7ccA0b4xA=wRXdgZ/neydxNfaMYNLwFwH4WtDMA+fZgbb4ZwPknek=-iBu1PdxvF7T1DxeCDWSWs0gEde1RW1JbJM1PeT0j6f4=
SHAPEmfsp8g4ERJkOuBoKG5ZXCsalol+Dw/i771nPJ//dVgc=DqqSYMg+bxFEw7N39M3GtciAXkCXiARdDIWaUyRmbZw=kSzhOSbTGMpI7IB6Lhmvs7ElYRuDy1gW/OsXJyHm7WI=-sx523C3ZYiddSQ0TJoicp7dZSXba9ARU1CnfqWlLJpw=
SONEIUMJ/oTg21YADvP5STmtJ62qKv3dVLCBiIebjCw6s2SS0U=r9XtmkpoYKTw6TWuHxy6+ASoX8bHl0ZB9sR2RdsQrVA=sLGXj47SqEnZ5Ndfiwz7WuuEarFWnv3iRcIVpJNBROY=5cxOotfRvkVUHBXfoGxyQiGuqrhGAox3TuNfKI3/OMQ=8+lPnL/LSKHm+umCoV5gJLTGmcNTV3elkkulCCsCoqg=
SWANcKyxsE76OBtW8ZNZWbH7gfXN/+CVM47PPGPssGvmSgU=GudxCxGrnuRl4MITnpHCIAtZZ25wmiNhDCJCBgEiIqs=l0nAxz8Nf5mvjapPWC+vZBKNFQe4YqKNezfvCizBK38=-gT4s4pNWxbhzR/3DycM5to0g4TsFIUuRmSuV7EOInus=
SWELLenAqApLFF0jQqKXu62ukTqWj+6W7NF/f3zyLrihWrzU=mO+/sxrE4vJZfrQO3bFjYtMT9iK/RfGdXoDkekY5Bh8=RfHL3VdykEYL02vCdCSTFZHi066z9/DsUF7uTS5F7/g=EZt+fei9OcaI4qH4/VOs+DqUGF5o56BmQLE2EX/ur9o=Am3N4BBwxACUKPAVFDa0fsbxW+Jr+GAfC/Pyl6U3zeo=
UNICHAIN0RQFDOuKSFfEwcleGnTGb7lM+vZg9nBzZ9WyzOye1js=RPbKsmdW0/HirF7l75QQd0Nl02deTVxOCCrFFupKHq0=sfq4QRqSyFpW9LqR7rw2x4gk+vhC87Ny3MNPpz77y/I=+hPVJiVcO3aF1fsFSDQs0hNhv6Ebtu/G8e1JbaL2lEU=R9tEDC01Bad5RkKenWotOIuPVJUlTwHhste5/YO0L/o=
WORLDCHAINjVe/Dpr1TgIxBLbkMoLKmXWTJthxFB0LhHrxWQmt548=hXw/qm4zZq7F+r3+FpPwE11FA6TD7H/cnY0+t697fq0=xak+QMrTI2r97/oFyvE45Wmpqe9r+P4E5pLhyGswjWc=waUx+j75/SloH+se3JVW3oDt2Z8AgvO/QwcxMwoOKkI=jhH5vIoiz/7mwgCrpDEyEeCnhtNGn+MXgEXgAzSrn8s=
XTERIO91Lmuq3ndcnbZwqO7660c9j2fAQSVnhTEVR8rWec17M=4Bi3sOZJ/iDa6Z4pvWMi0IrTTd/oHMqqKqjMKUkjWSQ=/s2yXOol2pPAkxCtBO+45y4olRrFIPWRGymDJ4k28Wc=-TrlgnoqdDxLQZP09awG12o31j3qEiDv6WTaYjz5E7Ng=
ZORAgqPrgjDFJo0cxqAjtajifVr4f+ODszjovnISfmqT3qA=cgfAWKq1l/V12yl1VKIGxFDmaFuotwck19DV+KGl6XY=7B968iepoM5KgO93Lo/9rnvqkud1scMnSVHcSCThEbc=yDQTF2Jvodg/6XgVmx5t3QdDy4BGMqyi/JMa2U4jQMA=nK05Pdeg9M6n0mrOXYiFIopRs5t/tzDWwMIHJLmmPX8=

Note: A dash (-) indicates that the metric is not available for that chain.

Project Rewards

warning

These metrics are currently calculated out of band and are not part of our funding events dataset. They will be replaced with a new set of metric IDs (and names) soon.

We have created some temporary Metric IDs to store project rewards for S7.

Metric NameMetric ID
S7_M1_devtooling_reward0dWueJWVz1tnXyCQv+vPE9IqED5s1uD3ag2VEA4CDAw=
S7_M1_onchain_builder_rewardR6eoyOPpiinCi8etN5D/qzAGcOxs8caCXTBrPCUarw4=

These are available ONLY in the metrics_v0 and timeseries_metrics_by_project_v0 tables.

Eligibility Criteria

Current eligibility criteria include:

  • 1000 transactions (contract invocations) in the 180-day period
  • 10 days with onchain activity in the 180-day period

The example query grabs the data necessary to check if a project meets these criteria for the period ending 2025-02-28.

query CheckProjectEligibility(
$projectId: String!,
$startDate: Oso_Date!,
$endDate: Oso_Date!
) {
# Get contract invocation metrics for the 180-day period
contractInvocations: oso_timeseriesMetricsByProjectV0(
where: {
projectId: { _eq: $projectId },
sampleDate: { _gte: $startDate, _lte: $endDate },
metricId: { _in: [
"OVljq6aZt9O5d5Bk0RpoAEXJ+nJr80fkry5+f7RUuRk=", # OPTIMISM
"8vTagJLAu5fbgEOQ6nqnLsRqbQ7dDOQANWfiaPKDVPc=", # BASE
"WOxUb39soikSlTz0N9gJZh9UkU5v8+TLRAFanTBWHhE=" # INK
# This should be extended to include all chains
] }
}
order_by: [ {
sampleDate: Desc
}]
) {
metricId
sampleDate
amount
}
}

Variables:

{
"projectId": "5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ=",
"startDate": "2024-09-02",
"endDate": "2025-02-28"
}

The response will include the contract invocation metrics for the project over the specified period. In order to check if the project meets the eligibility criteria, you need to:

  1. Sum the amount field to get the total number of transactions across all chains.
  2. Count the number of distinct sampleDate values to get the number of days with onchain activity.

You can then compare these values to the eligibility criteria to determine if the project is eligible.

Coverage testing

Here is a query you can run in py-oso to test the coverage of the metrics:

#! pip install pyoso

from dotenv import load_dotenv
import os
import pandas as pd
from pyoso import Client

load_dotenv()
OSO_API_KEY = os.environ['OSO_API_KEY']
client = Client(api_key=OSO_API_KEY)

metrics = [
f"{c.upper()}_{m}"
for c in [ # Supported chains
'automata', 'base', 'bob', 'cyber', 'frax', 'ham', 'ink',
'kroma', 'lisk', 'lyra', 'metal', 'mint', 'mode', 'optimism',
'orderly', 'polynomial', 'race', 'redstone', 'shape', 'soneium',
'swan', 'swell', 'unichain', 'worldchain', 'xterio', 'zora'
]
for m in [ # Metric types
'defillama_tvl_daily',
'gas_fees_daily',
'transactions_daily',
'contract_invocations_daily',
'active_addresses_aggregation_daily'
]
]
query = f"""
WITH metric_ids AS (
SELECT DISTINCT
metric_id,
metric_name
FROM metrics_v0
WHERE metric_name IN ({"'" + "','".join(metrics) + "'"})
),
metric_stats AS (
SELECT
tm.metric_id,
COUNT(DISTINCT tm.project_id) as project_count,
MIN(tm.sample_date) as first_date,
MAX(tm.sample_date) as last_date,
AVG(tm.amount) as mean_value
FROM timeseries_metrics_by_project_v0 tm
GROUP BY tm.metric_id
)
SELECT
mi.metric_id,
mi.metric_name,
ms.project_count,
ms.first_date,
ms.last_date,
ms.mean_value
FROM metric_ids mi
LEFT JOIN metric_stats ms ON mi.metric_id = ms.metric_id
ORDER BY mi.metric_name
"""
df = client.to_pandas(query)

You can also check coverage for a specific project:

#! pip install pyoso

from dotenv import load_dotenv
import os
import pandas as pd
from pyoso import Client

load_dotenv()
OSO_API_KEY = os.environ['OSO_API_KEY']
client = Client(api_key=OSO_API_KEY)

project_id = '5/9fRbVoDF7pHwBdiMbNUbKhidEt/12Ojt9f8cWoZnQ='

query = f"""
SELECT
m.metric_id,
m.metric_name,
MIN(tm.sample_date) AS first_date,
MAX(tm.sample_date) AS last_date,
MAX(tm.amount) AS max_amount
FROM timeseries_metrics_by_project_v0 AS tm
JOIN metrics_v0 AS m ON tm.metric_id = m.metric_id
WHERE tm.project_id = '{project_id}'
GROUP BY m.metric_id, m.metric_name
"""
df = client.to_pandas(query)