Kupo

The Kupo chain-index HTTP API for Cardano, hosted by Demeter.

What it is for

Looking up unspent outputs by address, payment or stake credential, policy id or asset, with their datums and scripts. Lucid Evolution's Kupmios provider pairs a Kupo port with an Ogmios port: Kupo answers the UTxO queries and Ogmios submits transactions and reads the ledger. Any HTTP client can call it directly.

Demeter's Kupo serves unspent outputs only. A /matches request with spent, spent_after or spent_before returns 400. For the API itself, see the API reference.

Hosts

The pattern, where {network} is cardano-mainnet, cardano-preprod or cardano-preview:

https://{network}-v2.kupo-m1.dmtr.host

On preprod:

https://cardano-preprod-v2.kupo-m1.dmtr.host

The authenticated form puts the key in the host:

https://{key}.{network}-v2.kupo-m1.dmtr.host

Authentication

Send the key in the dmtr-api-key header:

dmtr-api-key: <your key>

Or use the authenticated host, with no header, for clients that cannot set one.

Networks

cardano-mainnet, cardano-preprod and cardano-preview. Each port serves one network, chosen when you create it.

Limits

TierMinimum feePer 100k requestsMax requests / secondDaily requests
Free$0$05~430,000
Flexible$0$0.3020~1,700,000
Pro I$50$0.26100~8,600,000
Pro II$150$0.23300~26,000,000

Usage is counted per 100,000 requests, and throughput is capped by requests per second. Minimum fees apply only to the tiers that reserve throughput.

Getting a key

Create a Kupo port at https://console.demeter.run. The port's page shows its endpoint, its authenticated endpoint and its API key.

Example

Set the key and an address in your shell:

export DEMETER_API_KEY=...   # the API key from the port's page
export ADDRESS=addr_test1... # any preprod address

With curl, the unspent outputs at that address on preprod:

curl -H "dmtr-api-key: $DEMETER_API_KEY" \
  "https://cardano-preprod-v2.kupo-m1.dmtr.host/matches/$ADDRESS?unspent"

Kupmios with Lucid Evolution

Kupmios takes the Kupo and Ogmios URLs and a header for each. The two ports have separate keys, so this reads two variables (checked against @lucid-evolution/lucid 0.8.2):

import { Kupmios, Lucid } from "@lucid-evolution/lucid";

const provider = new Kupmios(
  "https://cardano-preprod-v2.kupo-m1.dmtr.host",
  "https://cardano-preprod-v6.ogmios-m1.dmtr.host",
  {
    kupoHeader: { "dmtr-api-key": process.env.DEMETER_KUPO_API_KEY! },
    ogmiosHeader: { "dmtr-api-key": process.env.DEMETER_OGMIOS_API_KEY! },
  },
);

console.log(await provider.getUtxos(process.env.ADDRESS!));

const lucid = await Lucid(provider, "Preprod");
demeter

Infrastructure made easy. Developed by TxPipe, powered by the community.

© 2026 TXPIPE