Skip to content

Moving from the v1 API

This page is for you if your integration calls the v1 API: /api/wallet/create, /api/wallet/list or /api/withdraw, with an x-api-key header.

v1 stops at the cutover. From that moment the v1 API no longer answers, v1 keys no longer work, and v1 callbacks are no longer sent. There is no period in which both versions run. Your integration has to be on v2 at the cutover.

Your account and your funds move by themselves. Only your code has to change.

You do nothing for these.

In v2
Account and sign-in The same email and password.
Profile Your business and contact details.
Master wallets The same addresses, shown in the dashboard under Balances.
Deposit wallets They are reusable deposit addresses now, with the same addresses and the same names. Payments sent to them are still received.
Balances Unchanged.
History Your earlier transactions, shown under Payments and marked as imported.
  1. Call the v2 API, directly or with the Node SDK. The base URL is https://api.ctpeway.com and every path starts with /v1. See Requests and responses.
  2. Create a v2 API key. v1 keys do not work in v2. Create a secret key in the dashboard under Developers → API keys and send it as Authorization: Bearer <key>, not in x-api-key. See API keys.
  3. Add a v2 webhook endpoint. The callback URL of your v1 key is not used by v2. Register your URL under Developers → Webhooks, or with POST/v1/webhook_endpoints, and store its signing secret. See Webhooks.
  4. Verify the signature. v1 callbacks were not signed. Every v2 delivery has a Ctpeway-Signature header, and your handler should reject a delivery that does not verify. See Verify the signature.
  5. Handle the v2 event names and payloads. v2 sends named events in a common envelope, with different field names from the v1 callback. See The deposit webhook below.

v2 has a test mode with its own keys and a payment simulator, so you can build and test all of this without real funds.

What you do v1 v2
Authenticate x-api-key: <key> Authorization: Bearer <key>
Create a wallet for a customer POST /api/wallet/create POST/v1/deposit_addresses
List wallets GET /api/wallet/list GET/v1/deposit_addresses
Withdraw POST /api/withdraw POST/v1/payouts
Hear about a deposit The pending callback deposit.payment_detected, then deposit.payment_confirmed

Four differences to plan for:

  • Amounts are whole numbers of the asset’s smallest unit, written as strings, in requests and in events. Convert with the asset’s decimals. See Amounts.
  • A key cannot pay out until you allow it. Your v2 key needs the payout permission, granted when you create the key, and a limit on where it can send money. In v1 a withdrawal could go to any address on the chain. To keep that in v2, restrict the key to the IP addresses of your servers: it then pays any address that is valid on the payout’s network, and only in requests from those addresses. If you always pay the same few addresses, list them as the key’s payout allowlist instead, or use both. See API keys.
  • A payout needs an Idempotency-Key header, and it is checked before it is accepted. If it cannot be made, you get an error at once instead of finding out later. Its progress is then reported in events. See Idempotency.
  • Networks and assets are named by the v2 API. GET/v1/networks and GET/v1/assets list the names to use.

In v1 you received a callback with the status pending when a deposit was seen. In v2 the same deposit produces events:

Event Meaning What to do
deposit.payment_detected The deposit was seen on the network. Not final. Show it as pending, if you want to.
deposit.payment_confirmed The deposit is confirmed. Credit your customer.
deposit.payment_released The funds have been moved to your master wallet. Nothing.
payment.orphaned, payment.dropped A deposit that was seen is no longer on the network. Undo anything you did for it.

The fields you used in the v1 callback are in data.object of the event:

v1 callback v2 event
chain payment.network
txHash payment.tx_hash
token payment.asset
from, to payment.from_address, payment.address
name deposit_address.name
amount payment.amount, in the asset’s smallest unit, with payment.decimals
usdAmount payment.usd_value
blockHeight payment.block_height
status The event type, as in the table above.

Each event’s page under Webhook events lists every field.

Held deposits. The platform fee is 0.5% of each deposit, charged in the network’s native coin. A deposit in a token has its fee paid by your master wallet, and waits in its address, Held, until the master wallet can pay. In v2 you can see what is held and what it needs, in the dashboard and through the API. Funds that are in a deposit address at the cutover are settled by v2 under this rule. See Settlement and the platform fee.

Signing in. You sign in again once after the cutover. A code sent by WhatsApp keeps working as your second factor, and you can add an authenticator app.

New in v2. Invoices with a hosted checkout page, test mode, signed events with a log you can replay, and a Node SDK and command-line tool.