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.
Deprecation timeline
The v1 API was deprecated on July 24, 2026 and sunset on
August 21, 2026. It is now shut down: every v1 endpoint returns
410 Gone with a Link header pointing to this guide. All integrations must
be on v2.
| 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. |
v1 is sunset
v1 no longer accepts requests. The v1 documentation is kept for reference only, so you can map your existing integration onto v2 — do not build against it. If your integration was granted a sunset extension and you are still calling v1, reach out to coordinate your cutover.
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/{userId}/requirements, PATCH /v2/users/{userId}, 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
Registering a v2 webhook does not disable v1 webhooks, so if you had v1 webhooks configured they keep firing alongside v2 until you turn them off:
- 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 webhooks, use the PATCH /webhooks call — it remains available for this purpose after the sunset — 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