MeterCall Oracle

Pay-per-query oracle feeds. Signed reports your smart contract can verify on-chain. 99% cheaper than Chainlink.

Quickstart

One fetch. Every response is a signed report.

const r = await fetch('https://metercall.ai/v1/oracle/price/ETH-USD');
const report = await r.json();

// {
//   feed_id: "price/ETH-USD",
//   feed_id_hash: "0x...",
//   value: 2847.33,
//   timestamp: 1713312451200,
//   digest: "0x...",
//   signature: "0x...",
//   signer: "0x..."
// }

Or use the SDK:

const { MeterCallOracle } = require('metercall-oracle');
const oracle = new MeterCallOracle({ key: 'mc_live_...' });
const r = await oracle.price('ETH-USD');

Pricing

Feed classMeterCallChainlink
Crypto price$0.0001 / query~$30/mo/feed
Stablecoin peg$0.0001 / query~$30/mo/feed
Gas price$0.0001 / query~$15/mo/feed
Forex$0.0001 / query~$50/mo/feed
TVL$0.0002 / querycustom only
Weather$0.0002 / querycustom only
Commodity / Stock$0.0003 / query$50–75/mo/feed
NFT floor$0.0005 / query$100+/mo/feed
Sports$0.001 / querycustom only
First 10,000 queries per month are free on every MeterCall plan. No monthly feed subscription, ever.

GET /v1/oracle/feeds

Returns the catalog plus the current signer and EIP-712 domain so contracts can compare on-chain.

// Response
{
  "feeds": [ { "id": "price", "example": "/v1/oracle/price/ETH-USD", ... } ],
  "custom_count": 18,
  "signer": "0xA1B2....",
  "domain": { "name": "MeterCallOracle", "version": "1", "chainId": 1, ... }
}

GET/v1/oracle/price/:pair

Supported pairs use BASE-QUOTE or BASE/QUOTE. Examples: ETH-USD, BTC-USD, SOL-USDC, XAU-USD, SPX-USD.

GET/v1/oracle/gas/:chain

Current gas price in gwei. Supported chains: ethereum. More chains rolling out via the ETH_RPC environment expansion.

GET/v1/oracle/tvl/:protocol

Total Value Locked in USD. Backed by DefiLlama. Protocol slugs: aave, uniswap, curve, lido, etc.

GET/v1/oracle/nft/:collection/floor

NFT floor price in USD. Collection slugs match CoinGecko NFT IDs (cryptopunks, bored-ape-yacht-club, pudgy-penguins).

GET/v1/oracle/sport/:league/:event

Live scores and event outcomes. Populated by MeterCall's sports harvester bots.

GET/v1/oracle/weather/:lat/:lon

Current weather (temperature °C, wind km/h, precipitation mm) for coordinates. Backed by Open-Meteo.

GET/v1/oracle/fx/:from-:to

Forex rate. Example: /v1/oracle/fx/USD-EUR.

GET/v1/oracle/custom/:id

Reads a previously registered custom feed. Same signed-report shape as the built-ins.

POST/v1/oracle/custom

Register a new custom feed. Requires header x-admin-key.

// Request body
{
  "id": "uni-v3-eth-usdc-tick",
  "description": "Uniswap v3 ETH/USDC current tick",
  "source_url": "https://example.com/api/tick",
  "json_path": "data.tick"
}

After registration, any query to /v1/oracle/custom/uni-v3-eth-usdc-tick fetches the source, extracts the path, and returns a signed report.

Response shape

{
  "feed_id": "price/ETH-USD",
  "feed_id_hash": "0xd3...",   // sha256(feed_id)
  "value": 2847.33,
  "timestamp": 1713312451200,  // unix ms
  "digest": "0x...",
  "signature": "0x...",       // 65-byte ECDSA
  "signer": "0xA1B2...",
  "domain": {
    "name": "MeterCallOracle",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0x..."
  }
}

Solidity verifier

Drop OracleConsumer.sol into your project. Inherit and call verifyMeterCall(report) before consuming any value.

import "./OracleConsumer.sol";

contract Vault is OracleConsumer {
    constructor(address signer) OracleConsumer(signer, 1, address(this)) {}

    function liquidate(Report calldata r) external {
        verifyFeed(r, "price/ETH-USD");
        require(block.timestamp - (r.timestamp / 1000) < 60, "stale");
        // r.value is int256 scaled 1e8 — safe to use
    }
}

JavaScript SDK

oracle.js is dependency-free and works in browsers and Node 18+.

const oracle = new MeterCallOracle({ key: MC_KEY });

await oracle.price('BTC-USD');
await oracle.gas('ethereum');
await oracle.tvl('aave');
await oracle.nftFloor('cryptopunks');
await oracle.fx('USD', 'EUR');
await oracle.weather(40.71, -74.00);

// Convert to on-chain shape
const r = await oracle.price('ETH-USD');
const onchain = oracle.toOnchainReport(r);

Caching & freshness

The timestamp field is always the moment of harvest, not the moment of HTTP response. Enforce your own freshness budget on-chain via maxReportAge in OracleConsumer.

Error codes

HTTPerrorMeaning
400bad_pairPair isn't in BASE-QUOTE form.
400bad_coordslat/lon not a number.
400bad_idCustom feed id has invalid characters.
401unauthorizedMissing or wrong x-admin-key.
404feed_not_foundCustom id not registered.
502no_dataUpstream returned nothing for the key.
502upstream_*Upstream returned a non-2xx; status code embedded.