> ## Documentation Index
> Fetch the complete documentation index at: https://nexus.gerowallet.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Maestro: Cardano

> Endpoint-by-endpoint map from Maestro's Cardano APIs to the native Nexus Cardano API

Maestro's developer API retires on September 18, 2026, per their announcement of August 18, 2026:
every endpoint is retired and keys stop working on that date. This page maps the Maestro Cardano
surface to its Nexus equivalent, path by path.

The base URL becomes `https://nexus.gerowallet.io` (Maestro's Cardano services sit under
`https://mainnet.gomaestro-api.org/v1`, with `preprod` and `preview` hosts alongside it), and the
credential becomes an `X-Api-Key: nxs_...` header in place of Maestro's `api-key`. See
[Authentication](/docs/authentication) for how keys are issued and scoped.

<Note>
  If your code already speaks a Blockfrost SDK, you have a shorter path. Maestro's own retirement
  notice points Cardano users at Blockfrost, and Nexus serves a Blockfrost-compatible surface at
  `/api/v0`: point the SDK's `customBackend` at it, pass your `nxs_` key as the `project_id`, and
  the migration is one line. See [Blockfrost Compatibility](/docs/blockfrost-compatibility). The map
  below is for teams calling Maestro over plain HTTP, or moving to the native API on purpose.
</Note>

## Endpoint map

Maestro paths are shown relative to their `/v1` base. Nexus paths are absolute.

Two paging shapes appear below. The older reads page with `page` and `pageSize`. The reads added
for this migration page with `cursor` and `limit`: the response carries a `nextCursor`, and you
send it back as `cursor` for the next page. That token is opaque and endpoint-specific, so do not
build one, parse one, or carry a Maestro cursor into it. An absent `nextCursor` is the last page.
`limit` defaults to 50 and caps at 200 unless the row says otherwise.

### Accounts

| Maestro                                  | Nexus                                         | Notes                                                                                                                                                                         |
| ---------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /accounts/{stake_addr}`             | `GET /api/account/{stakeAddress}/info`        | Account root moves under an explicit `/info` leaf                                                                                                                             |
| `GET /accounts/{stake_addr}/addresses`   | `GET /api/account/{stakeAddress}/addresses`   |                                                                                                                                                                               |
| `GET /accounts/{stake_addr}/assets`      | `GET /api/account/{stakeAddress}/assets`      |                                                                                                                                                                               |
| `GET /accounts/{stake_addr}/rewards`     | `GET /api/account/{stakeAddress}/rewards`     |                                                                                                                                                                               |
| `GET /accounts/{stake_addr}/delegations` | `GET /api/account/{stakeAddress}/delegations` | Delegation certificates newest first, `{poolId, txHash, slot, epoch, certIndex}`, pool as bech32 `pool1...`. Cursor-paged                                                     |
| `GET /accounts/{stake_addr}/updates`     | `GET /api/account/{stakeAddress}/updates`     | Registrations and deregistrations in one stream, each tagged `action: REGISTRATION` or `DEREGISTRATION`. Cursor-paged                                                         |
| `GET /accounts/{stake_addr}/history`     | `GET /api/account/{stakeAddress}/history`     | Per-epoch stake snapshots `{epoch, activeStake, poolId}`, newest epoch first, from the chain database. An account never snapshotted is an empty page, not a 404. Cursor-paged |

Nexus adds two account reads with no Maestro counterpart: `GET /api/account/{stakeAddress}/utxos`
and `GET /api/account/{stakeAddress}/txs`.

### Addresses

| Maestro                                         | Nexus                                               | Notes                                                                                                                                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /addresses/{address}/utxos`                | `GET /api/addresses/{address}/utxos`                | Filter to one asset with `GET /api/addresses/{address}/utxos/{asset}`                                                                                                                                                                                                                                                                                                                                       |
| `POST /addresses/utxos`                         | `POST /api/addresses/utxos`                         | Body `{"addresses": [...]}`, at most **50** per call. Every address comes back in request order with an empty `utxos` array when it holds nothing, so the response zips against the request                                                                                                                                                                                                                 |
| `GET /addresses/{address}/utxo_refs`            | `GET /api/addresses/{address}/utxos`                | No reference-only route. Read the full UTxOs and project `{txHash, outputIndex}` client-side                                                                                                                                                                                                                                                                                                                |
| `GET /addresses/{address}/transactions`         | `GET /api/addresses/{address}/transactions/history` | Returns the full per-transaction history in one call, not just references                                                                                                                                                                                                                                                                                                                                   |
| `GET /addresses/{address}/transactions/count`   | `GET /api/addresses/{address}/transactions/count`   | Distinct transactions that funded or spent an output, over the whole history, from the chain database. An address the chain has never seen counts `0` rather than 404ing. Very hot addresses can exceed the statement timeout and return **504**                                                                                                                                                            |
| `GET /addresses/{address}/decode`               | `GET /api/addresses/decode/{address}`               | The address moves to the END of the path. Pure computation, no chain read: Shelley bech32 and Byron base58 both accepted, and Byron reports era and type `byron` with no credentials and no `network` (Byron carries its network in a protocol-magic attribute that is not parsed)                                                                                                                          |
| `GET /addresses/cred/{credential}/utxos`        | `GET /api/addresses/cred/{credential}/utxos`        | Paged with `page` and `pageSize`; optional `fromSlot` and `toSlot` bounds                                                                                                                                                                                                                                                                                                                                   |
| `POST /addresses/cred/utxos`                    | `POST /api/addresses/cred/utxos`                    | Body `{"credentials": [...]}`, at most **25** per call. Lower than the address batch's 50 because a credential is not one address but every address under it                                                                                                                                                                                                                                                |
| `GET /addresses/cred/{credential}/balance`      | `GET /api/addresses/cred/{credential}/balance`      | Total lovelace plus one entry per native asset, summed inside Postgres over the same unspent set `/utxos` pages through. A credential holding nothing returns a zero balance, not a 404                                                                                                                                                                                                                     |
| `GET /addresses/cred/{credential}/transactions` | `GET /api/addresses/cred/{credential}/transactions` | Served from the chain database wherever one is configured, which in production is every network, and from the provider chain otherwise. Newest first by transaction id, so ties inside a block order by position rather than by hash. A very busy credential can exceed the statement timeout and return **504**, and narrowing `fromSlot`/`toSlot` does not avoid it: the window is applied after the join |
| `POST /addresses/cred/transactions`             | `POST /api/addresses/cred/transactions`             | At most **25** credentials. `limit` applies PER credential, so one busy credential cannot crowd the others out of the batch                                                                                                                                                                                                                                                                                 |

Every `cred` path takes the payment credential as a 56-character hex key hash, the same value
`GET /api/addresses/decode/{address}` reports under `paymentCredential.hash`.

### Assets and policies

| Maestro                             | Nexus                                                                | Notes                                                                                                                                                                                                                                                                                                                          |
| ----------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `GET /assets/{asset}`               | `GET /api/assets/detailedInfo?assetPolicy={policy}&assetName={name}` | The single concatenated `{asset}` path segment splits into two query parameters, both hex                                                                                                                                                                                                                                      |
| `GET /assets/{asset}/addresses`     | `GET /api/assets/{unit}/holders`                                     | `unit` is `policy + name` concatenated, the same string Maestro calls `{asset}`. Entries are `{address, quantity}`, sorted by quantity descending, paged with `page` and `pageSize`                                                                                                                                            |
| `GET /assets/{asset}/utxos`         | `GET /api/assets/{unit}/utxos`                                       | Same `unit` format                                                                                                                                                                                                                                                                                                             |
| `GET /assets/{asset}/accounts`      | `GET /api/assets/{unit}/accounts`                                    | The same holdings as `/holders`, grouped by stake account so a wallet spread over many payment addresses appears once. A holding whose outputs carry no stake part appears under its own payment address. Aggregates the LIVE UTxO set with no snapshot behind it, so a whale asset can exceed the query timeout. Cursor-paged |
| `GET /assets/{asset}/mints`         | `GET /api/assets/{unit}/mints`                                       | Every mint and burn, newest first. A burn carries a negative `quantity`, so the column sums to current supply. Cursor-paged                                                                                                                                                                                                    |
| `GET /assets/{asset}/transactions`  | `GET /api/assets/{unit}/transactions`                                | Every transaction that put the asset into an output or minted or burned it, newest first, from the chain database. A page can be SHORTER than `limit` and still carry a `nextCursor`, so follow the cursor until it is absent rather than until a page comes back short                                                        |
| `GET /policy/{policy}/assets`       | `GET /api/policy/{policyId}/assets`                                  |                                                                                                                                                                                                                                                                                                                                |
| `GET /policy/{policy}/utxos`        | `GET /api/policy/{policyId}/utxos`                                   |                                                                                                                                                                                                                                                                                                                                |
| `GET /policy/{policy}/mints`        | `GET /api/policy/{policyId}/mints`                                   | The asset mints view widened to the policy, each row naming the `unit` it applies to. Cursor-paged                                                                                                                                                                                                                             |
| `GET /policy/{policy}/addresses`    | `GET /api/policy/{policyId}/addresses`                               | Addresses holding any asset under the policy, largest first; the quantity sums every asset under the policy the address holds. Aggregates the LIVE UTxO set, so a top-ten fungible token can exceed the query timeout. Cursor-paged                                                                                            |
| `GET /policy/{policy}/accounts`     | `GET /api/policy/{policyId}/accounts`                                | The same holdings grouped by stake account, with the same cost and the same best-effort page stability                                                                                                                                                                                                                         |
| `GET /policy/{policy}/transactions` | `GET /api/policy/{policyId}/transactions`                            | Transactions that produced the policy's currently-unspent outputs. Narrower than every transaction that touched the policy: a transaction whose policy outputs have all since been spent does not appear, and neither does any spend side. Use `/policy/{policyId}/mints` for supply events. Cursor-paged                      |

### Blocks, epochs and protocol parameters

| Maestro                            | Nexus                              | Notes                                                                                                                                                                                                                 |
| ---------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /blocks/latest`               | `GET /api/blocks/latest`           |                                                                                                                                                                                                                       |
| `GET /blocks/{hash_or_height}`     | `GET /api/blocks/{hash}`           | By hash. For a recent-blocks listing use `GET /api/blocks`                                                                                                                                                            |
| `GET /general/chain-tip`           | `GET /api/blocks/latest`           | The latest block carries the tip height, hash and slot; there is no separate tip route                                                                                                                                |
| `GET /epochs/current`              | `GET /api/epoch/latest`            |                                                                                                                                                                                                                       |
| `GET /epochs/{epoch_no}`           | `GET /api/epoch/{epochNo}`         | Block and transaction counts, total output, total fees, the epoch's time boundaries and its snapshotted active stake, from the chain database                                                                         |
| `GET /general/protocol-parameters` | `GET /api/epoch/latest/parameters` | `GET /api/epoch/params` serves the same parameters for tooling that prefers that shape                                                                                                                                |
| `GET /general/era-summaries`       | `GET /api/network/era-summaries`   | Oldest era first, each with `{era, name, startSlot, startEpoch, slotLengthMs, epochLength}`. Byron is synthesized from the Shelley boundary rather than read, so it alone carries no `startBlock` or `startBlockHash` |
| `GET /general/system-start`        | `GET /api/network/system-start`    | A genesis constant, not a chain read, returned as both `unixTime` seconds and an ISO-8601 `isoTime`                                                                                                                   |

### Datums and scripts

| Maestro                      | Nexus                                | Notes                                                                                                                                                                                                                                                                                     |
| ---------------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /datums/{datum_hash}`   | `GET /api/scripts/datum/{datumHash}` | Datums live under the scripts resource                                                                                                                                                                                                                                                    |
| `POST /datums`               | `POST /api/scripts/datums`           | Body `{"hashes": [...]}`, at most **100**. Every requested hash is a key of the response's `data` object, in request order; a hash with no datum on chain maps to `null` rather than being dropped. Values are hex CBOR only, without the single-datum endpoint's best-effort JSON decode |
| `GET /scripts/{script_hash}` | `GET /api/scripts/{scriptHash}`      |                                                                                                                                                                                                                                                                                           |

### Ecosystem

| Maestro                             | Nexus                       | Notes                                                                                                                                                                                                                                                                                                         |
| ----------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /ecosystem/adahandle/{handle}` | `GET /api/handles/{handle}` | Accepts the handle with or without its leading `$` and in any casing. Both the legacy bare-name token and the CIP-68 user token are matched, and the CIP-68 one wins when both are unspent. A live token lookup, so it changes the moment the handle is spent to someone else. Served from the chain database |

### Stake pools

| Maestro                           | Nexus                                | Notes                                                                                                                      |
| --------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `GET /pools`                      | `GET /api/pools`                     |                                                                                                                            |
| `GET /pools/{pool_id}/info`       | `GET /api/pools/{id}`                | Pool detail is the resource root, with no `/info` leaf                                                                     |
| `GET /pools/{pool_id}/history`    | `GET /api/pools/{poolId}/history`    | Single-epoch slice: `GET /api/pools/{poolId}/epochs/{epoch}`                                                               |
| `GET /pools/{pool_id}/delegators` | `GET /api/pools/{poolId}/delegators` | Cursor-paged with `limit` defaulting to 100 and capping at 500, not the usual 50/200. Three behavioural differences, below |

Delegators are the one row in this map whose behaviour differs enough to plan around. The native
endpoint returns
`{ "epoch": 651, "data": [{ "stakeAddress": "stake1...", "liveStake": "1137959159981411" }], "nextCursor": "..." }`.
The same data is served on `/api/v0` in Blockfrost's own
`[{ "address": ..., "live_stake": ... }]` shape with its `count` and `page` parameters, so an
unmodified Blockfrost SDK reaches it too. Three behaviours to fold into a client:

* **Snapshot, not live.** The figures come from the newest stake snapshot, which trails the chain
  tip by one epoch. The native envelope names that epoch; the Blockfrost shape has no field for it.
* **Ordered by stake address.** The underlying table carries no slot or certificate column, so no
  chain order is recoverable from it. Page 1 is therefore not the page 1 hosted Blockfrost returns.
  `order=desc` on `/api/v0` reverses that address ordering, which is the opposite of the key that
  exists rather than the opposite of Blockfrost's. The set of delegators across all pages is the
  same either way.
* **Offset depth on `/api/v0`.** Blockfrost's offset pages are emulated over the native cursor, so
  `/api/v0` pages only as deep as offset 2000, which is page 21 at `count=100`. Past that it answers
  **400** naming the native endpoint. Walk `/api/pools/{poolId}/delegators` with its `nextCursor`
  when you need the whole list; that path has no depth limit.

### Transactions

| Maestro                                           | Nexus                                  | Notes                                                                                              |
| ------------------------------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `GET /transactions/{tx_hash}`                     | `GET /api/transactions/{txHash}`       |                                                                                                    |
| `GET /transactions/{tx_hash}/cbor`                | `GET /api/transactions/{txHash}/cbor`  |                                                                                                    |
| `POST /transactions/evaluate`                     | `POST /api/transactions/evaluate`      | Redeemer evaluation                                                                                |
| `POST /transactions/outputs`                      | `POST /api/transactions/utxos`         | Body is a JSON array of `{"txHash": "...", "outputIndex": 0}`, between 1 and 100 items per call    |
| `GET /transactions/{tx_hash}/outputs/{index}/txo` | `GET /api/transactions/{txHash}/utxos` | Returns every input and output of the transaction; select the index you want client-side           |
| `POST /txmanager`                                 | `POST /api/transactions/submit`        | Submission is a plain endpoint, not a managed queue. See the note on the Transaction Manager below |

Nexus also serves transaction metadata that has no Maestro equivalent:
`GET /api/transactions/{txHash}/metadata` and `GET /api/transactions/{txHash}/metadata/cbor`.

## Where there is no native equivalent

Two Maestro reads have no native Nexus route, plus the two product surfaces described after them.
Everything else on Maestro's Cardano API appears in the map above.

Before writing client-side aggregation for anything, check the Blockfrost-compatible surface at
`/api/v0`: it serves reads the native API has no route of its own for, among them the per-pool
`metadata`, `relays`, `updates` and `blocks` sub-resources. See
[Blockfrost Compatibility](/docs/blockfrost-compatibility) for the full list of what that surface serves
and what it guards.

**Not served on either surface**:

* `GET /policy/{policy}`, the policy summary root. Its `/assets`, `/utxos`, `/mints`, `/addresses`,
  `/accounts` and `/transactions` sub-resources are all mapped above, so the underlying facts are
  reachable; only the one aggregate document is not.
* `GET /pools/{pool_id}/delegators/{epoch_no}`. Only the newest stake snapshot is readable. The
  epoch-scoped variant is not guarded on `/api/v0` and times out against the upstream aggregation,
  so treat historical delegator lists as unavailable rather than as a route to point at today. The
  plain `/pools/{pool_id}/delegators` is served, with the caveats listed under Stake pools.

<Note>
  Maestro's Transaction Manager has no Nexus counterpart. `POST /txmanager` maps cleanly to
  `POST /api/transactions/submit`, but `POST /txmanager/turbosubmit`,
  `GET /txmanager/{txhash}/state`, `GET /txmanager/history` and `POST /webhooks/project/{project_id}`
  do not. Nexus submits the transaction and returns; tracking confirmation means polling
  `GET /api/transactions/{txHash}`, or subscribing over
  [WebSocket streaming](/docs/addons/websockets) where your plan includes it.
</Note>

Nexus does not serve Maestro's Managed Contracts API (vesting, direct swap, single-asset staking,
subscription, multisig). That is application logic rather than chain data, and there is no
equivalent surface to migrate it onto.

## Auth, base URL and network selection

Three differences to fold into your client, all mechanical.

**The header.** Maestro's `api-key` header becomes `X-Api-Key`, carrying a key that starts with
`nxs_`. Keys are created in the dashboard and shown once.

**The base URL.** Maestro selects a network by hostname (`mainnet.`, `preprod.`, `preview.`) plus a
`/v1` version segment. Nexus has one host for everything, `https://nexus.gerowallet.io`, and no
version segment on the native API.

**The network.** Nexus selects the network by key, not by hostname. Each key is bound at creation
time to one chain-and-network pair, `CARDANO_MAINNET`, `CARDANO_PREPROD` or `CARDANO_PREVIEW`, so a
mainnet key cannot read preprod. Most endpoints accept an optional `network` query parameter; omit
it and the request runs against the key's own network. Sending one that disagrees with the key
returns **400 Network Mismatch**.

<CodeGroup>
  ```bash Maestro theme={null}
  curl -X GET "https://mainnet.gomaestro-api.org/v1/addresses/$ADDRESS/utxos" \
    -H "api-key: your_maestro_key"
  ```

  ```bash Nexus theme={null}
  curl -X GET "https://nexus.gerowallet.io/api/addresses/$ADDRESS/utxos" \
    -H "X-Api-Key: nxs_your_api_key_here"
  ```
</CodeGroup>

Because the network rides on the key, running Maestro and Nexus side by side during the cutover
means one extra key per network you read, not a second base-URL scheme. Both APIs work
independently until September 18.

## Why not the free one

Koios is a community-run, open-source Cardano API, and it costs nothing. A team leaving Maestro
can pick it, so here is the straight answer. Its published tiers
([koios.rest/tiers.html](https://koios.rest/tiers.html), checked 2026-09-07): public access with no
key at 5,000 requests a day and 100 requests per 10 seconds, a registered no-charge tier at 50,000
a day, then Pro at about $29.99 a month for 500,000 a day and Premium at about $74.99 for 1.2M.
Queries time out at 30 seconds on the free tiers, and support is best-effort from the node
operators who run it.

If your workload is Cardano-only chain reads under 50,000 requests a day and best-effort uptime is
acceptable, Koios is a good answer. Where it stops: it is Cardano only, so a Maestro user with
Bitcoin reads needs a second provider; it is chain data only, with no market data, streaming,
transaction builder or wallet analytics; and there is no one on the hook when it is down. Nexus
counts requests monthly with no daily reset (2M on Builder at \$29), raises the per-second limit
with the plan (25, 50, 100 req/s), covers Bitcoin and Midnight on the same account, and keeps
Koios itself in the fallback path behind its Cardano reads, so nothing is lost by choosing it.

## What to test first

Nine checks that surface the differences that actually break code.

1. **A UTxO read on a known address.** Confirms the header swap and that your key is scoped to the
   network you think it is.
2. **An asset lookup.** `GET /api/assets/detailedInfo` takes `assetPolicy` and `assetName` as
   separate query parameters, so anything that concatenated the two into one path segment needs a
   split. Asset holders and asset UTxOs keep the concatenated `unit` form, so both shapes exist and
   it is easy to send the wrong one.
3. **`GET /api/network/era-summaries`.** One cheap call that pins the era arithmetic every
   slot-to-time conversion depends on. Mainnet answers with seven entries, Byron through Conway,
   Conway starting at epoch 507.
4. **One bulk call.** `POST /api/addresses/utxos` with two addresses. Batch bodies are the biggest
   shape change in this map, and they are the calls whose caps bite first: 50 addresses, 100 datum
   hashes, 25 credentials.
5. **A cursor page followed twice.** `GET /api/pools/{poolId}/delegators` on a large pool, then the
   same call with the returned `nextCursor`. Anything that assumed Maestro's cursors, or that stops
   when a page comes back shorter than `limit`, breaks here.
6. **A historical epoch.** `GET /api/epoch/500` on mainnet returns `fees` of `67528053731`. Fees are
   the reason to ask about a closed epoch, so they are the field worth asserting on.
7. **A handle resolve.** `GET /api/handles/charles`. Confirms the ADA Handle move off
   `/ecosystem/adahandle/{handle}` and, because a handle is a live token, that you are reading a
   current holder rather than a cached one.
8. **A deliberate network mismatch.** Send `?network=CARDANO_PREPROD` on a mainnet key and confirm
   your error handling reads the 400 body rather than retrying.
9. **A transaction submit on preprod.** Submission returns immediately with no managed state to
   poll, so any code that waited on a Transaction Manager state transition needs its own
   confirmation loop against `GET /api/transactions/{txHash}`.

Then check **rate limit behaviour under your real burst**. Metering is per request rather than per
credit, so your call volume translates directly. Check the per-tier numbers on
[Rate Limits](/docs/concepts/rate-limits) against your peak.

## Next steps

<CardGroup cols={2}>
  <Card title="Migrate from Maestro: Bitcoin" icon="bitcoin" href="/docs/maestro-migration-bitcoin">
    The Bitcoin half of the same migration
  </Card>

  <Card title="Blockfrost Compatibility" icon="right-left" href="/docs/blockfrost-compatibility">
    The one-line path for code that already speaks a Blockfrost SDK
  </Card>

  <Card title="Authentication" icon="key" href="/docs/authentication">
    Key creation, scoping, and the `network` parameter
  </Card>

  <Card title="API Reference" icon="book" href="/docs/api-reference">
    The native Nexus surface, endpoint by endpoint
  </Card>
</CardGroup>
