Verify login code
curl --request POST \
--url https://api.example.com/api/v1/partner/auth/verifyconst options = {method: 'POST'};
fetch('https://api.example.com/api/v1/partner/auth/verify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.example.com/api/v1/partner/auth/verify"
response = requests.post(url)
print(response.text)Login
Verify login code
Verify the one-time code and receive a QASH access token for the user.
POST
/
api
/
v1
/
partner
/
auth
/
verify
Verify login code
curl --request POST \
--url https://api.example.com/api/v1/partner/auth/verifyconst options = {method: 'POST'};
fetch('https://api.example.com/api/v1/partner/auth/verify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.example.com/api/v1/partner/auth/verify"
response = requests.post(url)
print(response.text)Requires
X-Api-Key and X-Api-Secret headers. See Authentication for details.accessToken — the same session token used by the QASH app itself. Every financial and card endpoint after this point uses that token, not your API key.
POST /partner/auth/send → user receives a 6-digit code by email
POST /partner/auth/verify → { accessToken, refreshToken }
Request
POST /api/v1/partner/auth/verify
X-Api-Key: <your-api-key>
X-Api-Secret: <your-api-secret>
Content-Type: application/json
{
"email": "juan@example.com",
"code": "482913"
}
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The email the code was sent to |
code | string | Yes | The 6-digit code from the email |
Response — 200 OK
{
"success": true,
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"user": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "juan@example.com",
"status": "active"
}
}
| Field | Type | Description |
|---|---|---|
accessToken | string | Bearer token for all financial and card endpoints. Short-lived. |
refreshToken | string | Long-lived token to obtain a new accessToken without re-verifying |
user.status | string | Always "active" on a successful login |
Store
accessToken and refreshToken in your backend on behalf of the user — do not expose them to client-side code unless your integration is designed to hand sessions directly to a client app.Using the access token
Authorization: Bearer <accessToken>
X-Api-Key or userId needed. The token already identifies the user and your partner account.
Errors
Failure responses share one generic message to avoid revealing account state to unauthenticated callers:{
"success": false,
"error": "Invalid or expired code"
}
| Status | Error | Cause |
|---|---|---|
401 | Invalid or expired code | Wrong code, expired code, or the email/user does not belong to your partner scope |
401 | User account is {status} | The user exists and the code was correct, but their status isn’t active yet (still pending, kyc_required, suspended, or banned) — finish KYC first |
401 | Invalid partner credentials | Wrong X-Api-Key or X-Api-Secret |