Skip to content

Repository files navigation

Ribbit Network API

A public API for global CO2 measurements, powered by the Ribbit Network — an open-source network of citizen-operated CO2 sensors.

📖 Documentation

Interactive API reference (try requests in the browser): api.ribbitnetwork.org/docs

Machine-readable OpenAPI spec: api.ribbitnetwork.org/openapi.yaml

The spec also lives in this repo at internal/docs/openapi.yaml and is the source of truth — use it to generate client SDKs (openapi-generator, oapi-codegen, etc.) or to import into Postman / Insomnia / Bruno.

Quickstart

No key needed to get started — fetch the last day of CO2 readings on the free tier:

curl "https://api.ribbitnetwork.org/data?start=2024-01-01T00:00:00Z&stop=2024-01-02T00:00:00Z&fields=co2,lat,lon&interval=1h"

An API key is optional and unlocks much higher rate limits — pass it as a header:

curl -H "Authorization: Bearer $RIBBIT_API_KEY" \
"https://api.ribbitnetwork.org/data?start=2024-01-01T00:00:00Z&stop=2024-01-02T00:00:00Z&fields=co2,lat,lon&interval=1h"

Endpoints at a glance:

EndpointAuthDescription
GET /Health banner (🐸)
GET /healthzLiveness check (ok)
GET /docsInteractive API reference
GET /dataoptionalSensor measurements over a time range
GET /sensorsoptionalList of known sensor IDs

See /docs for full parameter, response, and error documentation.

Rate limits

TierLimited bySustained rateBurst
Free (no key)client IP1 request / minute5
KeyedAPI key1 request / second60

The free tier is sized for polling a single sensor about once a minute. For more sensors or faster polling. Exceeding the limit returns 429 Too Many Requests with a Retry-After header.

If you would like an API key for faster data access etc, please send an email to hello @ ribbitnetwork.org with a brief description of your usecase and who you are. :)

Running locally

Prerequisites:Go 1.25+

  1. Clone the repo:

    git clone https://github.com/Ribbit-Network/api &&cd api
  2. Copy the example env file and fill in your InfluxDB credentials:

    cp .env.example .env
  3. Run:

    go run .

The API will be available at http://localhost:8080, and the interactive docs at http://localhost:8080/docs.

Previewing just the docs

If you only want to render the OpenAPI page (no InfluxDB or API-key store needed), run:

go run . docs

This serves the embedded spec and Scalar reference at http://localhost:8080. Handy when iterating on internal/docs/openapi.yaml.

Environment variables

VariableDescription
PORTPort to listen on (e.g. 8080)
INFLUXDB_SERVER_URLInfluxDB Cloud instance URL
INFLUXDB_AUTH_TOKENInfluxDB API token (use a read-only token in production)
INFLUXDB_ORGInfluxDB organization name or email
INFLUXDB_BUCKETInfluxDB bucket name (frog_fleet)
API_KEY_DB_PATHPath to the SQLite file holding hashed API keys
SENSORS_CACHE_TTLHow long the /sensors list is cached (Go duration, e.g. 10m; default 5m)

API keys

/data and /sensors are open to anonymous callers on the free tier; an API key is optional and raises the rate limit to the keyed tier. A key that is sent but invalid or revoked is rejected with 401 rather than downgraded to the free tier. Keys live in a SQLite file at API_KEY_DB_PATH; only the SHA-256 of each key is stored.

Key management is built into the API binary as a keygen subcommand.

Locally:

# Issue a new key (the raw key is printed once — record it immediately)
go run . keygen issue --owner you@example.com
# List existing keys
go run . keygen list
# Revoke a key by ID
go run . keygen revoke --id 3

In production (on Fly.io), run the same subcommands against the deployed binary over SSH:

fly ssh console -C "/api keygen issue --owner researcher@uni.edu"
fly ssh console -C "/api keygen issue --owner you@example.com"
fly ssh console -C "/api keygen list"
fly ssh console -C "/api keygen revoke --id 7"

Callers pass the key in either header:

curl -H "Authorization: Bearer rbnt_...""$API_URL/data?start=2024-01-01T00:00:00Z"
curl -H "X-API-Key: rbnt_...""$API_URL/data?start=2024-01-01T00:00:00Z"

Updating the docs

The OpenAPI spec at internal/docs/openapi.yaml is embedded into the binary at build time. When you add or change an endpoint:

  1. Edit the spec to match.
  2. go build ./... to verify it still compiles (the spec is go:embed-ed).
  3. Visit /docs locally to spot-check the rendered output.

Contributing

Feel free to open an issue or PR! We also have enabled the Github discussion board if you prefer that.

About

A public API for global CO2 measurements, powered by the Ribbit Network

Topics

Resources

Stars

4 stars

Watchers

2 watching

Forks

Used by

Contributors

Languages