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.
| Date | Milestone |
|---|---|
| July 24, 2026 | Deprecated. v2 becomes the required API for all integrations. v1 keeps working but receives no further updates or fixes. |
| August 21, 2026 | Sunset. 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_name→firstName,address1→addressLine1,postal→postalCode). - 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.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john.doe@example.com"
}{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john.doe@example.com"
}
}{
"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 endpoint | v2 endpoint |
|---|---|
POST /loginCodeSend | POST /v2/auth/login-codes |
POST /loginCodeVerify | POST /v2/auth/login-codes/verify |
POST /generateApiLink | POST /v2/users + GET /v2/users/{userId}/kyc-url |
GET /apiFindUser | GET /v2/users?email={email} |
POST /sumsubImportUser | PUT /v2/users/{userId}/kyc |
GET /priceQuote | GET /v2/quotes |
GET /transaction | GET /v2/transactions + GET /v2/transactions/{txId} |
POST /transaction | POST /v2/transactions |
GET, PATCH /webhooks | GET, PUT, DELETE /v2/webhook-configurations |
POST /webhook-signing-secret | POST /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
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" }'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:
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.
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
}'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:
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
curl -X GET "https://api.paytrie.com/priceQuote?leftSideLabel=CAD&leftSideValue=100&rightSideLabel=USDC-ETH" \
-H "x-api-key: your-api-key"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.
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
}'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:
- Register your v2 webhook URL with
PUT /v2/webhook-configurations. - Confirm v2 events are arriving at your endpoint.
- 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:
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