Paytrie Developer Documentation

Migration Guide

Move your existing v1 API integration to the v2 API

This guide walks through migrating an existing v1 integration to the v2 API. v2 is not backwards compatible, but most changes are mechanical — a new base path, camelCase fields, and a consistent response envelope — with a few flows (user creation, authentication) split into clearer, dedicated endpoints. v1 keeps working while you migrate, up to the sunset date below.

Deprecation timeline

The v1 API is deprecated as of July 24, 2026 and sunset on August 21, 2026. It keeps working between those dates but receives no further updates or fixes. On August 21 it shuts down and stops accepting requests, so you must be fully migrated to v2 by then.

DateMilestone
July 24, 2026Deprecated. v2 becomes the required API for all integrations. v1 keeps working but receives no further updates or fixes.
August 21, 2026Sunset. v1 shuts down and stops accepting requests. All integrations must be on v2 by this date.

Sunset date

v1 will be sunset on August 21, 2026. All integrations must be on v2 by then. If you need more time, reach out before the sunset date to request an extension and we'll work with you.

What changed at a glance

  • Versioned base path — every endpoint now lives under /v2.
  • Consistent response envelope — successful responses are wrapped in { "success": true, "data": ... }; errors return { "success": false, "errors": [...] }.
  • camelCase everywhere — request and response fields use camelCase (first_namefirstName, address1addressLine1, postalpostalCode).
  • RESTful, resource-based endpoints — verb-style endpoints (/generateApiLink, /loginCodeSend) are replaced with resources (/users, /auth/login-codes).
  • Separated authentication — integrator requests use x-api-key; requests made on behalf of an end user now use a short-lived JWT (Authorization: Bearer <token>).

Base URL

- https://api.paytrie.com/<endpoint>
+ https://api.paytrie.com/v2/<endpoint>

Response envelope

v1 returned the payload (or an ad-hoc { status, message } object) directly. v2 always wraps the payload so success and errors are predictable.

v1 response
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "john.doe@example.com"
}
v2 response
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "john.doe@example.com"
  }
}
v2 error
{
  "success": false,
  "errors": [{ "field": "email", "message": "Invalid email" }]
}

Update your client to read the payload from response.data and to check response.success (or the HTTP status) for errors.

Endpoint mapping

v1 endpointv2 endpoint
POST /loginCodeSendPOST /v2/auth/login-codes
POST /loginCodeVerifyPOST /v2/auth/login-codes/verify
POST /generateApiLinkPOST /v2/users + GET /v2/users/{userId}/kyc-url
GET /apiFindUserGET /v2/users?email={email}
POST /sumsubImportUserPUT /v2/users/{userId}/kyc
GET /priceQuoteGET /v2/quotes
GET /transactionGET /v2/transactions + GET /v2/transactions/{txId}
POST /transactionPOST /v2/transactions
GET, PATCH /webhooksGET, PUT, DELETE /v2/webhook-configurations
POST /webhook-signing-secretPOST /v2/webhook-configurations/signing-secret/rotate

New in v2 with no v1 equivalent: GET /v2/limits, GET /v2/users/me/requirements, and PUT /v2/transactions/{txId}/cancel.

Migration examples

Request a login code

v1
curl -X POST "https://api.paytrie.com/loginCodeSend" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "email": "user@example.com" }'
v2
curl -X POST "https://api.paytrie.com/v2/auth/login-codes" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "email": "user@example.com" }'

Then exchange the code for a JWT:

v2
curl -X POST "https://api.paytrie.com/v2/auth/login-codes/verify" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "email": "user@example.com", "code": "1234" }'

Create a user

User creation and KYC are now two steps: create the user, then request a KYC URL.

v1
curl -X POST "https://api.paytrie.com/generateApiLink" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com",
    "phone": "4165551234",
    "dob": "1990-01-15",
    "address1": "123 Main Street",
    "address2": "Suite 100",
    "city": "Toronto",
    "province": "on",
    "postal": "M5V1A1",
    "occupation": "Software Engineer",
    "pep": false,
    "tpd": false
  }'
v2
curl -X POST "https://api.paytrie.com/v2/users" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john.doe@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "dob": "1990-01-15",
    "phone": "4165551234",
    "addressLine1": "123 Main Street",
    "addressLine2": "Suite 100",
    "city": "Toronto",
    "province": "on",
    "postalCode": "M5V1A1",
    "occupation": "Software Engineer",
    "pep": false,
    "tpd": false
  }'

Then generate the KYC link with the returned id:

v2
curl -X GET "https://api.paytrie.com/v2/users/{userId}/kyc-url" \
  -H "x-api-key: your-api-key"

See Customer Onboarding for the full onboarding flow.

Fetch a price quote

v1
curl -X GET "https://api.paytrie.com/priceQuote?leftSideLabel=CAD&leftSideValue=100&rightSideLabel=USDC-ETH" \
  -H "x-api-key: your-api-key"
v2
curl -X GET "https://api.paytrie.com/v2/quotes?leftSideLabel=CAD&leftSideValue=100&rightSideLabel=USDC-ETH" \
  -H "x-api-key: your-api-key"

The v2 quote response is enveloped and adds a quoteId (pass it to POST /v2/transactions to lock in the rate) plus a fee breakdown.

Create a transaction

The v2 body drops the client-supplied ethCost and gasId fields — pricing is derived server-side from the quoteId.

v1
curl -X POST "https://api.paytrie.com/transaction" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "leftSideLabel": "CAD",
    "leftSideValue": 1000,
    "rightSideLabel": "USDC-ETH",
    "wallet": "0x05a238198541d076B4fc74254Cd426A8C8e84D32",
    "ethCost": 3440.64,
    "gasId": 2,
    "quoteId": 1
  }'
v2
curl -X POST "https://api.paytrie.com/v2/transactions" \
  -H "x-api-key: your-api-key" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "leftSideLabel": "CAD",
    "leftSideValue": 1000,
    "rightSideLabel": "USDC-ETH",
    "wallet": "0x05a238198541d076B4fc74254Cd426A8C8e84D32",
    "quoteId": 1
  }'

Migrate webhooks

You can adopt v2 webhooks without interrupting your existing v1 integration. Registering a v2 webhook does not disable v1, so both fire in parallel while you migrate. Move over before the sunset date, then turn off v1 yourself:

  1. Register your v2 webhook URL with PUT /v2/webhook-configurations.
  2. Confirm v2 events are arriving at your endpoint.
  3. Once you're confident, turn off v1 yourself.

To turn off v1, you don't need a new endpoint — use the existing v1 PATCH /webhooks call and set every enabled flag to false:

Disable v1 webhooks
curl -X PATCH "https://api.paytrie.com/webhooks" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "verifiedEmailEnabled": false,
    "transactionInitiatedEnabled": false,
    "transactionCompleteEnabled": false,
    "transactionStatusUpdateEnabled": false
  }'

See Webhooks for the full v2 webhook setup, payload schemas, and signature verification.

Next steps

v2 API Reference

Browse the full list of v2 endpoints, parameters, and response schemas

Need help migrating?

Reach out and we'll help you plan the migration

On this page