Skip to main content

Migrating from the Service Provider API to the Network Partner API

This guide is for teams who already integrated White-Label discovery against the legacy Service Provider API (/service-providers/properties/* and /service-providers/limits/*) and need to move to the new Network Partner API (/network-partner/*). It maps every legacy discovery call to its replacement, shows the before/after request and response for each, and lists the behavioral changes to watch for.
Only discovery moved. The three transaction endpoints are unchanged — you do not need to touch them:
  • POST /payments/crypto/quote
  • POST /crypto/session/widget
  • GET /payments/transactions/{transactionId}
Authentication is also unchanged: Authorization: BASIC {apiKey} on every request, against https://api-sb.meld.io (sandbox) or https://api.meld.io (production). Network Partner routes carry per-method limits as of Meld-Version: 2026-02-03.

What changed at a glance

  1. Everything is category-scoped. Each discovery call now takes a category — for the retail ramp that is CRYPTO_ONRAMP (buy) or CRYPTO_OFFRAMP (sell). The legacy endpoints were direction-agnostic; the new ones return results for one direction at a time.
  2. One currencies endpoint. The separate fiat-currencies and crypto-currencies endpoints merged into a single supported/currencies call, switched by type=FIAT|CRYPTO.
  3. Limits moved into routes. There is no standalone limits endpoint. Per-(partner, payment-method) min/max now live on supported/routes, alongside the partners and rails that serve a currency pair — so limits are now direction-aware.
  4. Response shapes changed. Several fields were renamed and a few were added or dropped (see each section below).
  5. Routes are ordered by direction. The source/destination path segments follow the flow direction, not “fiat then crypto” (see Routes).

Endpoint mapping

The rest of this page walks each row in detail.

1. Countries

What changed
  • Now requires category (CRYPTO_ONRAMP or CRYPTO_OFFRAMP). The supported set can differ by direction, so call it once per direction you offer.
  • countryNamename, and a flag emoji is now included.
  • states[] is no longer returned here. Collect the US state in your own UI and pass it as the subdivision query param on Routes.

2. Country defaults

What changed
  • Country and category are now path params (/defaults/{country}/{category}), not a countries= query list.
  • The response is a single object (or null), no longer an array — drop the countryDefaults[0] indexing.
  • defaultCurrencyCodecurrencyCode, defaultPaymentMethodspaymentMethods.
Handle a null response — fall back to the first entry from Currencies and Payment methods when a country has no configured default.

3. Currencies

The two legacy endpoints are now one, switched by type.
What changed
  • One endpoint for both sides — pass type=FIAT or type=CRYPTO. category and country are required.
  • The legacy crypto list was returned under a cryptoCurrencies wrapper; both fiat and crypto now return a single currencies wrapper.
  • currencyNamename; networkCodechainCode; networkName is dropped.
  • New fields: decimalPlaces (use it for client-side formatting), symbol, and contract (token contract address) to disambiguate tokens on the same chain.
  • Optional filters: network (e.g. ETHEREUM, SOLANA), partner, paymentType, providerCurrencyCode.
For off-ramp, swap the category to CRYPTO_OFFRAMP: the type=CRYPTO list is what the user can sell, and type=FIAT is what they can receive.

4. Payment methods

After — response (bare array)
What changed
  • Now requires all three of category, country, and currencyCode (the fiat code — pay-with for buy, payout for sell). The legacy call keyed only off fiatCurrencies.
  • Returns a bare array (not an object wrapper).
Send method, never name. The canonical id you pass downstream as paymentMethodType is method (e.g. ACH, SEPA, CREDIT_DEBIT_CARD). name is a display label only and must never be sent to Meld — sending the wrong rail yields NO_VALID_QUOTES.

5. Limits and routes

This is the biggest structural change. The standalone limits endpoint is gone; limits now live on the route that serves a given currency pair, so they arrive together with the partners and rails that actually support that pair.
What changed
  • Limits are read from route.paymentMethods[].limits for the chosen partner + method, not from a global map keyed by currency.
  • minAmountmin, maxAmountmax; the limits.currencyCode tells you which currency the bounds are expressed in (on-ramp: the fiat paid; off-ramp: the fiat received).
  • Limits are now direction-aware — a buy route and a sell route for the same pair can have different min/max.
  • Path order follows direction:
    • On-ramp: .../CRYPTO_ONRAMP/{country}/{fiat}/{crypto} (source = fiat).
    • Off-ramp: .../CRYPTO_OFFRAMP/{country}/{crypto}/{fiat} (source = crypto).
  • Optional query params: partners, paymentMethod, paymentType, and subdivision (the US state that legacy countries.states[] used to carry).
Empty 200 [] is the new failure mode. Routes are indexed by source/destination, so reversing them — e.g. fiat-first on an off-ramp — returns HTTP 200 with an empty array, not a 404. It silently starves rail and limit discovery. Assert the array is non-empty before rendering rails or validating an amount.

Migration checklist

1

Add a category to every discovery call

Decide the direction per screen — CRYPTO_ONRAMP for buy, CRYPTO_OFFRAMP for sell — and thread it through every /network-partner/* call.
2

Repoint and rename the endpoints

Swap each legacy path for its replacement using the mapping table, and update the response field names (countryNamename, defaultCurrencyCodecurrencyCode, currencyNamename, networkCodechainCode, minAmount/maxAmountmin/max).
3

Merge the currency calls

Replace fiat-currencies and crypto-currencies with a single supported/currencies call parameterized by type=FIAT|CRYPTO, and read from the currencies wrapper.
4

Move limit validation onto routes

Delete calls to /service-providers/limits/*. Read min/max from route.paymentMethods[].limits, and order the route source/destination by direction.
5

Handle the new edge cases

Treat a null defaults response and an empty 200 [] from routes as expected states, and send the canonical method id (never the display name) as paymentMethodType.
6

Re-test both directions in sandbox

Run a buy and a sell against https://api-sb.meld.io end to end before switching to production credentials.

What stays the same

  • POST /payments/crypto/quote, POST /crypto/session/widget, and GET /payments/transactions/{transactionId} are unchanged.
  • Authorization: BASIC {apiKey} auth and the sandbox/production base URLs are unchanged.
  • The overall flow — discover → quote → create session → launch the provider widget → track the transaction — is unchanged.

Next steps

Full Integration Guide

The complete /network-partner/* reference plus the end-to-end on-ramp and off-ramp flows.

Quickstart

Run a sandbox buy and sell in about 30 minutes.